aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2012-04-30 18:21:31 +0000
committerDavid Blaikie <dblaikie@gmail.com>2012-04-30 18:21:31 +0000
commitc1c0725978ed31253af5ef4849a124e8fc13ebbb (patch)
tree6791cd604e04ad55e52e4df905596ede3fa90983
parente7be1090e8cc8bfcda4f73fcad35d29e9e58b1c4 (diff)
Fix PR12378: provide conversion warnings on default args of function templates
Apparently we weren't checking default arguments when they were instantiated. This adds the check, fixes the lack of instantiation caching (which seems like it was mostly implemented but just missed the last step), and avoids implementing non-dependent default args (for non-dependent parameter types) as uninstantiated default arguments (so that we don't warn once for every instantiation when it's not instantiation dependent). Reviewed by Richard Smith. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155838 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaExpr.cpp6
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp9
-rw-r--r--test/SemaCXX/conversion.cpp19
3 files changed, 30 insertions, 4 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 87a67ff632..4ed588565f 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3300,9 +3300,11 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
if (Result.isInvalid())
return ExprError();
+ Expr *Arg = Result.takeAs<Expr>();
+ CheckImplicitConversions(Arg, Arg->getExprLoc());
+ Param->setDefaultArg(Arg);
// Build the default argument expression.
- return Owned(CXXDefaultArgExpr::Create(Context, CallLoc, Param,
- Result.takeAs<Expr>()));
+ return Owned(CXXDefaultArgExpr::Create(Context, CallLoc, Param, Arg));
}
// If the default expression creates temporaries, we need to
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 793ee0e50a..3635e64f3d 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1594,8 +1594,13 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm,
} else if (OldParm->hasUnparsedDefaultArg()) {
NewParm->setUnparsedDefaultArg();
UnparsedDefaultArgInstantiations[OldParm].push_back(NewParm);
- } else if (Expr *Arg = OldParm->getDefaultArg())
- NewParm->setUninstantiatedDefaultArg(Arg);
+ } else if (Expr *Arg = OldParm->getDefaultArg()) {
+ if (Arg->isInstantiationDependent() ||
+ OldDI->getType()->isInstantiationDependentType())
+ NewParm->setUninstantiatedDefaultArg(Arg);
+ else
+ NewParm->setDefaultArg(Arg);
+ }
NewParm->setHasInheritedDefaultArg(OldParm->hasInheritedDefaultArg());
diff --git a/test/SemaCXX/conversion.cpp b/test/SemaCXX/conversion.cpp
index a64b18721a..225bc837b5 100644
--- a/test/SemaCXX/conversion.cpp
+++ b/test/SemaCXX/conversion.cpp
@@ -81,3 +81,22 @@ void test3() {
#define FINIT int a3 = NULL;
FINIT // expected-warning {{implicit conversion of NULL constant to 'int'}}
}
+
+namespace test4 {
+ template<typename T>
+ void tmpl(char c = NULL, // expected-warning {{implicit conversion of NULL constant to 'char'}}
+ T a = NULL, // expected-warning {{implicit conversion of NULL constant to 'char'}} \
+ expected-warning {{implicit conversion of NULL constant to 'int'}}
+ T b = 1024) { // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1024 to 0}}
+ }
+
+ template<typename T>
+ void tmpl2(T t = NULL) {
+ }
+
+ void func() {
+ tmpl<char>(); // expected-note {{in instantiation of default function argument expression for 'tmpl<char>' required here}}
+ tmpl<int>(); // expected-note {{in instantiation of default function argument expression for 'tmpl<int>' required here}}
+ tmpl2<int*>();
+ }
+}