r256976 - Improve conditional checking during template instantiation.

Richard Trieu via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 6 13:11:18 PST 2016


Author: rtrieu
Date: Wed Jan  6 15:11:18 2016
New Revision: 256976

URL: http://llvm.org/viewvc/llvm-project?rev=256976&view=rev
Log:
Improve conditional checking during template instantiation.

When the condition in an if statement, while statement, or for loop is created
during template instantiation, it calls MakeFullExpr with only the condition
expression.  However, when these conditions are created for non-templated
code in the Parser, an additional SourceLocation is passed to MakeFullExpr.
The impact of this was that non-dependent templated code could produce
diagnostics that the same code outside templates would not.  Adding the missing
SourceLocation makes diagnostics consistent between templated and non-templated
code.

Modified:
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/SemaCXX/conversion.cpp

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=256976&r1=256975&r2=256976&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Wed Jan  6 15:11:18 2016
@@ -6128,7 +6128,7 @@ TreeTransform<Derived>::TransformIfStmt(
     }
   }
 
-  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.get()));
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.get(), S->getIfLoc()));
   if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
     return StmtError();
 
@@ -6223,7 +6223,8 @@ TreeTransform<Derived>::TransformWhileSt
     }
   }
 
-  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.get()));
+  Sema::FullExprArg FullCond(
+      getSema().MakeFullExpr(Cond.get(), S->getWhileLoc()));
   if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
     return StmtError();
 
@@ -6307,7 +6308,8 @@ TreeTransform<Derived>::TransformForStmt
     }
   }
 
-  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.get()));
+  Sema::FullExprArg FullCond(
+      getSema().MakeFullExpr(Cond.get(), S->getForLoc()));
   if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
     return StmtError();
 

Modified: cfe/trunk/test/SemaCXX/conversion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conversion.cpp?rev=256976&r1=256975&r2=256976&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/conversion.cpp (original)
+++ cfe/trunk/test/SemaCXX/conversion.cpp Wed Jan  6 15:11:18 2016
@@ -77,30 +77,8 @@ void test3() {
   // CHECK: note: expanded from macro 'FINIT'
 #define FINIT int a3 = NULL;
   FINIT // expected-warning {{implicit conversion of NULL constant to 'int'}}
-
-  // we don't catch the case of #define FOO NULL ... int i = FOO; but that seems a bit narrow anyway
-  // and avoiding that helps us skip these cases:
-#define NULL_COND(cond) ((cond) ? &a : NULL)
-  bool bl2 = NULL_COND(true); // don't warn on NULL conversion through the conditional operator across a macro boundary
-  if (NULL_COND(true))
-    ;
-  while (NULL_COND(true))
-    ;
-  for (; NULL_COND(true); )
-    ;
-  do ;
-  while(NULL_COND(true));
-
-#define NULL_WRAPPER NULL_COND(false)
-  if (NULL_WRAPPER)
-    ;
-  while (NULL_WRAPPER)
-    ;
-  for (; NULL_WRAPPER;)
-    ;
-  do
-    ;
-  while (NULL_WRAPPER);
+  // we don't catch the case of #define FOO NULL ... int i = FOO; but that
+  // seems a bit narrow anyway and avoiding that helps us skip other cases.
 
   int *ip = NULL;
   int (*fp)() = NULL;
@@ -157,3 +135,66 @@ namespace test7 {
     return nullptr; // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
   }
 }
+
+namespace test8 {
+  #define NULL_COND(cond) ((cond) ? &num : NULL)
+  #define NULL_WRAPPER NULL_COND(false)
+
+  // don't warn on NULL conversion through the conditional operator across a
+  // macro boundary
+  void macro() {
+    int num;
+    bool b = NULL_COND(true);
+    if (NULL_COND(true)) {}
+    while (NULL_COND(true)) {}
+    for (;NULL_COND(true);) {}
+    do {} while (NULL_COND(true));
+
+    if (NULL_WRAPPER) {}
+    while (NULL_WRAPPER) {}
+    for (;NULL_WRAPPER;) {}
+    do {} while (NULL_WRAPPER);
+  }
+
+  // Identical to the previous function except with a template argument.
+  // This ensures that template instantiation does not introduce any new
+  // warnings.
+  template <typename X>
+  void template_and_macro() {
+    int num;
+    bool b = NULL_COND(true);
+    if (NULL_COND(true)) {}
+    while (NULL_COND(true)) {}
+    for (;NULL_COND(true);) {}
+    do {} while (NULL_COND(true));
+
+    if (NULL_WRAPPER) {}
+    while (NULL_WRAPPER) {}
+    for (;NULL_WRAPPER;) {}
+    do {} while (NULL_WRAPPER);
+  }
+
+  // Identical to the previous function except the template argument affects
+  // the conditional statement.
+  template <typename X>
+  void template_and_macro2() {
+    X num;
+    bool b = NULL_COND(true);
+    if (NULL_COND(true)) {}
+    while (NULL_COND(true)) {}
+    for (;NULL_COND(true);) {}
+    do {} while (NULL_COND(true));
+
+    if (NULL_WRAPPER) {}
+    while (NULL_WRAPPER) {}
+    for (;NULL_WRAPPER;) {}
+    do {} while (NULL_WRAPPER);
+  }
+
+  void run() {
+    template_and_macro<int>();
+    template_and_macro<double>();
+    template_and_macro2<int>();
+    template_and_macro2<double>();
+  }
+}




More information about the cfe-commits mailing list