[PATCH] D128747: ISSUE - incorrect -Winfinite-recursion warning on potentially-unevaluated operand #21668

Prathit Aswar via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 28 11:24:33 PDT 2022


appmonster007 created this revision.
appmonster007 added a reviewer: aaron.ballman.
appmonster007 added a project: clang.
Herald added a project: All.
appmonster007 requested review of this revision.
Herald added a subscriber: cfe-commits.

Fixing issue "incorrect -Winfinite-recursion warning on potentially-unevaluated operand #21668”

By having dedicated visit function (`VisitCXXTypeidExpr`) for `typeid`, instead of using default (`VisitStmt`).
In this new function we skip over CFG build for unevaluated operands of `typeid`


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128747

Files:
  clang/lib/Analysis/CFG.cpp
  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) {
+  typeid(evaluated_recursive_function(x));
+  return q;
+}
+
+int unevaluated_recursive_function() {
+  typeid(unevaluated_recursive_function());
+  return 0;
+}
\ No newline at end of file
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;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D128747.440701.patch
Type: text/x-patch
Size: 2476 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220628/b8e8a501/attachment-0001.bin>


More information about the cfe-commits mailing list