Skip to content

Commit

Permalink
[clang] Fix ICE on invalid type parameters for concepts
Browse files Browse the repository at this point in the history
See PR48593.

Constraints with invalid type parameters were causing a null pointer
dereference.

Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>

Reviewed By: rsmith

Differential Revision: https://reviews.llvm.org/D98095
  • Loading branch information
mizvekov committed Mar 13, 2021
1 parent c9fd92d commit d4a8c73
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 34 deletions.
61 changes: 27 additions & 34 deletions clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1256,25 +1256,6 @@ getImageAccess(const ParsedAttributesView &Attrs) {
return OpenCLAccessAttr::Keyword_read_only;
}

static QualType ConvertConstrainedAutoDeclSpecToType(Sema &S, DeclSpec &DS,
AutoTypeKeyword AutoKW) {
assert(DS.isConstrainedAuto());
TemplateIdAnnotation *TemplateId = DS.getRepAsTemplateId();
TemplateArgumentListInfo TemplateArgsInfo;
TemplateArgsInfo.setLAngleLoc(TemplateId->LAngleLoc);
TemplateArgsInfo.setRAngleLoc(TemplateId->RAngleLoc);
ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
TemplateId->NumArgs);
S.translateTemplateArguments(TemplateArgsPtr, TemplateArgsInfo);
llvm::SmallVector<TemplateArgument, 8> TemplateArgs;
for (auto &ArgLoc : TemplateArgsInfo.arguments())
TemplateArgs.push_back(ArgLoc.getArgument());
return S.Context.getAutoType(
QualType(), AutoKW, false, /*IsPack=*/false,
cast<ConceptDecl>(TemplateId->Template.get().getAsTemplateDecl()),
TemplateArgs);
}

/// Convert the specified declspec to the appropriate type
/// object.
/// \param state Specifies the declarator containing the declaration specifier
Expand Down Expand Up @@ -1655,29 +1636,39 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
break;

case DeclSpec::TST_auto:
case DeclSpec::TST_decltype_auto: {
auto AutoKW = DS.getTypeSpecType() == DeclSpec::TST_decltype_auto
? AutoTypeKeyword::DecltypeAuto
: AutoTypeKeyword::Auto;

ConceptDecl *TypeConstraintConcept = nullptr;
llvm::SmallVector<TemplateArgument, 8> TemplateArgs;
if (DS.isConstrainedAuto()) {
Result = ConvertConstrainedAutoDeclSpecToType(S, DS,
AutoTypeKeyword::Auto);
break;
if (TemplateIdAnnotation *TemplateId = DS.getRepAsTemplateId()) {
TypeConstraintConcept =
cast<ConceptDecl>(TemplateId->Template.get().getAsTemplateDecl());
TemplateArgumentListInfo TemplateArgsInfo;
TemplateArgsInfo.setLAngleLoc(TemplateId->LAngleLoc);
TemplateArgsInfo.setRAngleLoc(TemplateId->RAngleLoc);
ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
TemplateId->NumArgs);
S.translateTemplateArguments(TemplateArgsPtr, TemplateArgsInfo);
for (const auto &ArgLoc : TemplateArgsInfo.arguments())
TemplateArgs.push_back(ArgLoc.getArgument());
} else {
declarator.setInvalidType(true);
}
}
Result = Context.getAutoType(QualType(), AutoTypeKeyword::Auto, false);
Result = S.Context.getAutoType(QualType(), AutoKW,
/*IsDependent*/ false, /*IsPack=*/false,
TypeConstraintConcept, TemplateArgs);
break;
}

case DeclSpec::TST_auto_type:
Result = Context.getAutoType(QualType(), AutoTypeKeyword::GNUAutoType, false);
break;

case DeclSpec::TST_decltype_auto:
if (DS.isConstrainedAuto()) {
Result =
ConvertConstrainedAutoDeclSpecToType(S, DS,
AutoTypeKeyword::DecltypeAuto);
break;
}
Result = Context.getAutoType(QualType(), AutoTypeKeyword::DecltypeAuto,
/*IsDependent*/ false);
break;

case DeclSpec::TST_unknown_anytype:
Result = Context.UnknownAnyTy;
break;
Expand Down Expand Up @@ -5962,6 +5953,8 @@ namespace {
if (!DS.isConstrainedAuto())
return;
TemplateIdAnnotation *TemplateId = DS.getRepAsTemplateId();
if (!TemplateId)
return;
if (DS.getTypeSpecScope().isNotEmpty())
TL.setNestedNameSpecifierLoc(
DS.getTypeSpecScope().getWithLocInContext(Context));
Expand Down
8 changes: 8 additions & 0 deletions clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,11 @@ namespace PR48384 {
True decltype(auto) h = (b);
static_assert(is_same_v<decltype(h), int&>);
}

namespace PR48593 {
template <class T, class U> concept a = true;
a<B> auto c = 0; // expected-error{{use of undeclared identifier 'B'}}

template<class> concept d = true;
d<,> auto e = 0; // expected-error{{expected expression}}
}

0 comments on commit d4a8c73

Please sign in to comment.