]> granicus.if.org Git - clang/commitdiff
[c++1z] In class template argument deduction, all declarators must deduce the same...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 10 Feb 2017 03:27:13 +0000 (03:27 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 10 Feb 2017 03:27:13 +0000 (03:27 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@294700 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp [new file with mode: 0644]

index fca2b82c5831e1d74cf52af2ee29ffe34a451ace..45e8cc535d193437763b2a0f7c2e2b576648d626 100644 (file)
@@ -1923,8 +1923,9 @@ def err_auto_var_deduction_failure_from_init_list : Error<
 def err_auto_new_deduction_failure : Error<
   "new expression for type %0 has incompatible constructor argument of type %1">;
 def err_auto_different_deductions : Error<
-  "'%select{auto|decltype(auto)|__auto_type}0' deduced as %1 in declaration "
-  "of %2 and deduced as %3 in declaration of %4">;
+  "%select{'auto'|'decltype(auto)'|'__auto_type'|template arguments}0 "
+  "deduced as %1 in declaration of %2 and "
+  "deduced as %3 in declaration of %4">;
 def err_auto_non_deduced_not_alone : Error<
   "%select{function with deduced return type|"
   "declaration with trailing return type}0 "
index abb9f510628465308c6b7b477fb197d3c0c4710c..2a082fc775b7fd6234a0f3cd8694ab2be6cff350 100644 (file)
@@ -11262,18 +11262,19 @@ Sema::BuildDeclaratorGroup(MutableArrayRef<Decl *> Group) {
       VarDecl *D = dyn_cast<VarDecl>(Group[i]);
       if (!D || D->isInvalidDecl())
         break;
-      AutoType *AT = D->getType()->getContainedAutoType();
-      if (!AT || AT->getDeducedType().isNull())
+      DeducedType *DT = D->getType()->getContainedDeducedType();
+      if (!DT || DT->getDeducedType().isNull())
         continue;
       if (Deduced.isNull()) {
-        Deduced = AT->getDeducedType();
+        Deduced = DT->getDeducedType();
         DeducedDecl = D;
-      } else if (!Context.hasSameType(AT->getDeducedType(), Deduced)) {
+      } else if (!Context.hasSameType(DT->getDeducedType(), Deduced)) {
+        auto *AT = dyn_cast<AutoType>(DT);
         Diag(D->getTypeSourceInfo()->getTypeLoc().getBeginLoc(),
              diag::err_auto_different_deductions)
-          << (unsigned)AT->getKeyword()
+          << (AT ? (unsigned)AT->getKeyword() : 3)
           << Deduced << DeducedDecl->getDeclName()
-          << AT->getDeducedType() << D->getDeclName()
+          << DT->getDeducedType() << D->getDeclName()
           << DeducedDecl->getInit()->getSourceRange()
           << D->getInit()->getSourceRange();
         D->setInvalidDecl();
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
new file mode 100644 (file)
index 0000000..8819799
--- /dev/null
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+template<typename T> struct A { constexpr A(int = 0) {} };
+A() -> A<int>;
+A(int) -> A<char>;
+
+static constexpr inline const volatile A a = {}; // ok, specifiers are permitted
+A b; // FIXME: An initializer is required
+A c [[]] {};
+
+A d = {}, e = {};
+A f(0), g{}; // expected-error {{template arguments deduced as 'A<char>' in declaration of 'f' and deduced as 'A<int>' in declaration of 'g'}}