[Sema] Fix a bug in enable_if condition instantiation.

During template instantiation, we currently fall back to just calling
Sema::SubstExpr for enable_if attributes that aren't value-dependent or
type-dependent. Since Sema::SubstExpr strips off any implicit casts
we've added to an expression, it's possible that this behavior will
leave us with an enable_if condition that's just a DeclRefExpr.
Conditions like that deeply confuse Sema::CheckEnableIf.

llvm-svn: 287187
This commit is contained in:
George Burgess IV 2016-11-17 01:33:54 +00:00
parent 41d72a8632
commit 004319554c
2 changed files with 16 additions and 3 deletions

View File

@ -179,7 +179,7 @@ static void instantiateDependentEnableIfAttr(
return;
Cond = Result.getAs<Expr>();
}
if (A->getCond()->isTypeDependent() && !Cond->isTypeDependent()) {
if (!Cond->isTypeDependent()) {
ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);
if (Converted.isInvalid())
return;
@ -332,8 +332,7 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
continue;
}
const EnableIfAttr *EnableIf = dyn_cast<EnableIfAttr>(TmplAttr);
if (EnableIf && EnableIf->getCond()->isValueDependent()) {
if (const auto *EnableIf = dyn_cast<EnableIfAttr>(TmplAttr)) {
instantiateDependentEnableIfAttr(*this, TemplateArgs, EnableIf, Tmpl,
New);
continue;

View File

@ -450,3 +450,17 @@ namespace member_loc {
.bar(); // expected-error{{no matching member function}}
}
}
// Prior bug: we wouldn't properly convert conditions to bools when
// instantiating templates in some cases.
namespace template_instantiation {
template <typename T>
struct Foo {
void bar(int a) __attribute__((enable_if(a, ""))); // expected-note{{disabled}}
};
void runFoo() {
Foo<double>().bar(0); // expected-error{{no matching}}
Foo<double>().bar(1);
}
}