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>(); + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits