summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td5
-rw-r--r--clang/lib/Sema/SemaDecl.cpp13
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp12
3 files changed, 22 insertions, 8 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index fca2b82c583..45e8cc535d1 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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 "
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index abb9f510628..2a082fc775b 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -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/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
new file mode 100644
index 00000000000..88197999cd9
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
@@ -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'}}
OpenPOWER on IntegriCloud