зеркало из https://github.com/microsoft/clang-1.git
Fix PR9276: We were missing the checks for auto deducing to different types in the same declaration group in the template instantiation case.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126279 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
74eed0ea03
Коммит
406c38e8c1
|
@ -864,6 +864,8 @@ public:
|
|||
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);
|
||||
|
|
|
@ -5055,6 +5055,19 @@ Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
|
|||
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 @@ Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
|
|||
// 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 @@ Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
|
|||
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 @@ Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
|
|||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1083,11 +1083,8 @@ public:
|
|||
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.
|
||||
|
|
|
@ -32,3 +32,28 @@ bool h(T t) {
|
|||
}
|
||||
|
||||
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>();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче