Hi,
PR9276 points out that we were missing the checks for auto deducing to
different types in the same declaration group in the template
instantiation case. The attached patch fixes this.
Since this is the last outstanding issue on auto, I'd like to update the
www to indicate it's supported. Changes for that are included (to be
checked in as a separate revision).
I'd also like to update this page:
http://clang.llvm.org/docs/LanguageExtensions.html#cxx_auto_type
... but I don't know where that lives.
Thanks,
Richard
Index: test/SemaCXX/dependent-auto.cpp
===================================================================
--- test/SemaCXX/dependent-auto.cpp (revision 126164)
+++ test/SemaCXX/dependent-auto.cpp (working copy)
@@ -32,3 +32,28 @@
}
bool b = h('x'); // expected-note {{here}}
+
+// PR 9276 - Make sure we check auto types deduce the same
+// in the case of a dependent initializer
+namespace PR9276 {
+ template<typename T>
+ void f() {
+ auto i = T(), j = 0; // expected-error {{deduced as 'long' in declaration of 'i' and deduced as 'int' in declaration of 'j'}}
+ }
+
+ void g() {
+ f<long>(); // expected-note {{here}}
+ f<int>();
+ }
+}
+
+namespace NoRepeatedDiagnostic {
+ template<typename T>
+ void f() {
+ auto a = 0, b = 0.0, c = T(); // expected-error {{deduced as 'int' in declaration of 'a' and deduced as 'double' in declaration of 'b'}}
+ }
+ // We've already diagnosed an issue. No extra diagnostics is needed for these.
+ template void f<int>();
+ template void f<double>();
+ template void f<char>();
+}
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h (revision 126164)
+++ include/clang/Sema/Sema.h (working copy)
@@ -864,6 +864,8 @@
DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
Decl **Group,
unsigned NumDecls);
+ DeclGroupPtrTy BuildDeclaratorGroup(Decl **Group, unsigned NumDecls,
+ bool TypeMayContainAuto = true);
void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
SourceLocation LocAfterDecls);
Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
Index: www/cxx_status.html
===================================================================
--- www/cxx_status.html (revision 126164)
+++ www/cxx_status.html (working copy)
@@ -216,10 +216,10 @@
</tr>
<tr>
<td>auto type deduction</td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
+ <td class="complete" align="center"></td>
+ <td class="complete" align="center"></td>
+ <td class="complete" align="center"></td>
+ <td class="complete" align="center"></td>
<td>7.1.6.2, 7.1.6.4</td>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1984.pdf">N1984</a></td>
</tr>
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h (revision 126164)
+++ lib/Sema/TreeTransform.h (working copy)
@@ -1083,11 +1083,8 @@
StmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
SourceLocation StartLoc,
SourceLocation EndLoc) {
- return getSema().Owned(
- new (getSema().Context) DeclStmt(
- DeclGroupRef::Create(getSema().Context,
- Decls, NumDecls),
- StartLoc, EndLoc));
+ Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls, NumDecls);
+ return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
}
/// \brief Build a new inline asm statement.
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp (revision 126164)
+++ lib/Sema/SemaDecl.cpp (working copy)
@@ -5055,6 +5055,19 @@
if (DS.isTypeSpecOwned())
Decls.push_back(DS.getRepAsDecl());
+ for (unsigned i = 0; i != NumDecls; ++i)
+ if (Decl *D = Group[i])
+ Decls.push_back(D);
+
+ return BuildDeclaratorGroup(Decls.data(), Decls.size(),
+ DS.getTypeSpecType() == DeclSpec::TST_auto);
+}
+
+/// BuildDeclaratorGroup - convert a list of declarations into a declaration
+/// group, performing any necessary semantic checking.
+Sema::DeclGroupPtrTy
+Sema::BuildDeclaratorGroup(Decl **Group, unsigned NumDecls,
+ bool TypeMayContainAuto) {
// C++0x [dcl.spec.auto]p7:
// If the type deduced for the template parameter U is not the same in each
// deduction, the program is ill-formed.
@@ -5062,14 +5075,16 @@
// between the deduced type U and the deduced type which 'auto' stands for.
// auto a = 0, b = { 1, 2, 3 };
// is legal because the deduced type U is 'int' in both cases.
- bool TypeContainsAuto = DS.getTypeSpecType() == DeclSpec::TST_auto;
- if (TypeContainsAuto && NumDecls > 1) {
+ if (TypeMayContainAuto && NumDecls > 1) {
QualType Deduced;
CanQualType DeducedCanon;
VarDecl *DeducedDecl = 0;
for (unsigned i = 0; i != NumDecls; ++i) {
if (VarDecl *D = dyn_cast<VarDecl>(Group[i])) {
AutoType *AT = D->getType()->getContainedAutoType();
+ // Don't reissue diagnostics when instantiating a template.
+ if (AT && D->isInvalidDecl())
+ break;
if (AT && AT->isDeduced()) {
QualType U = AT->getDeducedType();
CanQualType UCanon = Context.getCanonicalType(U);
@@ -5078,11 +5093,13 @@
DeducedCanon = UCanon;
DeducedDecl = D;
} else if (DeducedCanon != UCanon) {
- Diag(DS.getTypeSpecTypeLoc(), diag::err_auto_different_deductions)
+ Diag(D->getTypeSourceInfo()->getTypeLoc().getBeginLoc(),
+ diag::err_auto_different_deductions)
<< Deduced << DeducedDecl->getDeclName()
<< U << D->getDeclName()
<< DeducedDecl->getInit()->getSourceRange()
<< D->getInit()->getSourceRange();
+ D->setInvalidDecl();
break;
}
}
@@ -5090,12 +5107,7 @@
}
}
- for (unsigned i = 0; i != NumDecls; ++i)
- if (Decl *D = Group[i])
- Decls.push_back(D);
-
- return DeclGroupPtrTy::make(DeclGroupRef::Create(Context,
- Decls.data(), Decls.size()));
+ return DeclGroupPtrTy::make(DeclGroupRef::Create(Context, Group, NumDecls));
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits