appmonster007 updated this revision to Diff 440859. Repository: rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION https://reviews.llvm.org/D128747/new/ https://reviews.llvm.org/D128747 Files: clang/lib/Analysis/CFG.cpp clang/test/SemaCXX/typeinfo clang/test/SemaCXX/warn-infinite-recursion.cpp
Index: clang/test/SemaCXX/warn-infinite-recursion.cpp =================================================================== --- clang/test/SemaCXX/warn-infinite-recursion.cpp +++ clang/test/SemaCXX/warn-infinite-recursion.cpp @@ -1,5 +1,7 @@ // RUN: %clang_cc1 %s -fsyntax-only -verify -Winfinite-recursion +#include "typeinfo" + void a() { // expected-warning{{call itself}} a(); } @@ -171,3 +173,18 @@ } int wrapper_sum = test_wrapper<2>(); // expected-note{{instantiation}} + +struct Q { + virtual ~Q(){}; +}; + +Q q; +Q &evaluated_recursive_function(int x) { // expected-warning{{call itself}} + (void)typeid(evaluated_recursive_function(x)); // expected-warning {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}} + return q; +} + +int unevaluated_recursive_function() { + (void)typeid(unevaluated_recursive_function()); + return 0; +} \ No newline at end of file Index: clang/test/SemaCXX/typeinfo =================================================================== --- /dev/null +++ clang/test/SemaCXX/typeinfo @@ -0,0 +1,16 @@ +namespace std { + class type_info { + public: + virtual ~type_info(); + const char* name() const { return __name; } + bool operator==(const type_info& __arg) const { + return __name == __arg.__name; + } + + bool operator!=(const type_info& __arg) const { + return !operator==(__arg); + } + protected: + const char *__name; + }; +} Index: clang/lib/Analysis/CFG.cpp =================================================================== --- clang/lib/Analysis/CFG.cpp +++ clang/lib/Analysis/CFG.cpp @@ -564,6 +564,7 @@ AddStmtChoice asc); CFGBlock *VisitCXXThrowExpr(CXXThrowExpr *T); CFGBlock *VisitCXXTryStmt(CXXTryStmt *S); + CFGBlock *VisitCXXTypeidExpr(CXXTypeidExpr *S, AddStmtChoice asc); CFGBlock *VisitDeclStmt(DeclStmt *DS); CFGBlock *VisitDeclSubExpr(DeclStmt *DS); CFGBlock *VisitDefaultStmt(DefaultStmt *D); @@ -2220,6 +2221,9 @@ case Stmt::CXXTryStmtClass: return VisitCXXTryStmt(cast<CXXTryStmt>(S)); + case Stmt::CXXTypeidExprClass: + return VisitCXXTypeidExpr(cast<CXXTypeidExpr>(S), asc); + case Stmt::CXXForRangeStmtClass: return VisitCXXForRangeStmt(cast<CXXForRangeStmt>(S)); @@ -4045,6 +4049,28 @@ return VisitStmt(T, AddStmtChoice::AlwaysAdd); } +CFGBlock *CFGBuilder::VisitCXXTypeidExpr(CXXTypeidExpr *S, AddStmtChoice asc) { + if (asc.alwaysAdd(*this, S)) { + autoCreateBlock(); + appendStmt(Block, S); + } + + // C++ [expr.typeid]p3: + // When typeid is applied to an expression other than an glvalue of a + // polymorphic class type [...] [the] expression is an unevaluated + // operand. [...] + // We add only potentially evaluated statements to block to avoid + // CFG generation for unevaluated operands. + if (S && !S->isTypeDependent()) { + if (S->isPotentiallyEvaluated()) { + return VisitChildren(S); + } + } + + // Return block without CFG for unevaluated operands. + return Block; +} + CFGBlock *CFGBuilder::VisitDoStmt(DoStmt *D) { CFGBlock *LoopSuccessor = nullptr;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits