Skip to content

Commit

Permalink
Revert "[Concepts] Placeholder constraints and abbreviated templates"
Browse files Browse the repository at this point in the history
This reverts commit e57a9ab.

Parser/cxx2a-placeholder-type-constraint.cpp has MSan failures.

Present at 7b81c3f:
http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap-msan/builds/17133/steps/check-clang%20msan/logs/stdio
not present at eaa594f:
http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap-msan/builds/17132/steps/check-clang%20msan/logs/stdio

Stack trace:
```
==57032==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0xccfe016 in clang::AutoTypeLoc::getLocalSourceRange() const /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/include/clang/AST/TypeLoc.h:2036:19
    #1 0xcc56758 in CheckDeducedPlaceholderConstraints(clang::Sema&, clang::AutoType const&, clang::AutoTypeLoc, clang::QualType) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp:4505:56
    #2 0xcc550ce in clang::Sema::DeduceAutoType(clang::TypeLoc, clang::Expr*&, clang::QualType&, llvm::Optional<unsigned int>, bool) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp:4707:11
    #3 0xcc52407 in clang::Sema::DeduceAutoType(clang::TypeSourceInfo*, clang::Expr*&, clang::QualType&, llvm::Optional<unsigned int>, bool) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp:4457:10
    #4 0xba38332 in clang::Sema::deduceVarTypeFromInitializer(clang::VarDecl*, clang::DeclarationName, clang::QualType, clang::TypeSourceInfo*, clang::SourceRange, bool, clang::Expr*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Sema/SemaDecl.cpp:11351:7
    #5 0xba3a8a9 in clang::Sema::DeduceVariableDeclarationType(clang::VarDecl*, bool, clang::Expr*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Sema/SemaDecl.cpp:11385:26
    #6 0xba3c520 in clang::Sema::AddInitializerToDecl(clang::Decl*, clang::Expr*, bool) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Sema/SemaDecl.cpp:11725:9
    #7 0xb39c498 in clang::Parser::ParseDeclarationAfterDeclaratorAndAttributes(clang::Declarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::ForRangeInit*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/ParseDecl.cpp:2399:17
    #8 0xb394d80 in clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::SourceLocation*, clang::Parser::ForRangeInit*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/ParseDecl.cpp:2128:21
    #9 0xb383bbf in clang::Parser::ParseSimpleDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::Parser::ParsedAttributesWithRange&, bool, clang::Parser::ForRangeInit*, clang::SourceLocation*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/ParseDecl.cpp:1848:10
    #10 0xb383129 in clang::Parser::ParseDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::Parser::ParsedAttributesWithRange&, clang::SourceLocation*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/include/llvm/ADT/PointerUnion.h
    #11 0xb53a388 in clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*, clang::Parser::ParsedAttributesWithRange&) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/ParseStmt.cpp:221:13
    #12 0xb539309 in clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/ParseStmt.cpp:106:20
    #13 0xb55610e in clang::Parser::ParseCompoundStatementBody(bool) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/ParseStmt.cpp:1079:11
    #14 0xb559529 in clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/ParseStmt.cpp:2204:21
    #15 0xb33c13e in clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::LateParsedAttrList*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/Parser.cpp:1339:10
    #16 0xb394703 in clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::SourceLocation*, clang::Parser::ForRangeInit*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/ParseDecl.cpp:2068:11
    #17 0xb338e52 in clang::Parser::ParseDeclOrFunctionDefInternal(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec&, clang::AccessSpecifier) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/Parser.cpp:1099:10
    #18 0xb337674 in clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec*, clang::AccessSpecifier) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/Parser.cpp:1115:12
    #19 0xb334a96 in clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/Parser.cpp:935:12
    #20 0xb32f12a in clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, bool) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/Parser.cpp:686:12
    #21 0xb31e193 in clang::ParseAST(clang::Sema&, bool, bool) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Parse/ParseAST.cpp:158:20
    #22 0x80263f0 in clang::FrontendAction::Execute() /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Frontend/FrontendAction.cpp:936:8
    #23 0x7f2a257 in clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Frontend/CompilerInstance.cpp:965:33
    #24 0x8288bef in clang::ExecuteCompilerInvocation(clang::CompilerInstance*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:290:25
    #25 0xad44c2 in cc1_main(llvm::ArrayRef<char const*>, char const*, void*) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/tools/driver/cc1_main.cpp:239:15
    #26 0xacd76a in ExecuteCC1Tool(llvm::ArrayRef<char const*>) /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/tools/driver/driver.cpp:325:12
    #27 0xacc9fd in main /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/tools/driver/driver.cpp:398:12
    #28 0x7f7d82cdb2e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202e0)
    #29 0xa4dde9 in _start (/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/clang-11+0xa4dde9)
```
  • Loading branch information
sam-mccall committed Jan 23, 2020
1 parent a1e0b53 commit 5c02fe1
Show file tree
Hide file tree
Showing 53 changed files with 362 additions and 1,869 deletions.
7 changes: 2 additions & 5 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ class AtomicExpr;
class BlockExpr;
class BuiltinTemplateDecl;
class CharUnits;
class ConceptDecl;
class CXXABI;
class CXXConstructorDecl;
class CXXMethodDecl;
Expand Down Expand Up @@ -212,7 +211,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
mutable llvm::FoldingSet<DependentUnaryTransformType>
DependentUnaryTransformTypes;
mutable llvm::ContextualFoldingSet<AutoType, ASTContext&> AutoTypes;
mutable llvm::FoldingSet<AutoType> AutoTypes;
mutable llvm::FoldingSet<DeducedTemplateSpecializationType>
DeducedTemplateSpecializationTypes;
mutable llvm::FoldingSet<AtomicType> AtomicTypes;
Expand Down Expand Up @@ -1543,9 +1542,7 @@ class ASTContext : public RefCountedBase<ASTContext> {

/// C++11 deduced auto type.
QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword,
bool IsDependent, bool IsPack = false,
ConceptDecl *TypeConstraintConcept = nullptr,
ArrayRef<TemplateArgument> TypeConstraintArgs ={}) const;
bool IsDependent, bool IsPack = false) const;

/// C++11 deduction pattern for 'auto' type.
QualType getAutoDeductType() const;
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/AST/ASTNodeTraverser.h
Original file line number Diff line number Diff line change
Expand Up @@ -548,8 +548,8 @@ class ASTNodeTraverser
}

void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
if (const auto *E = D->getPlaceholderTypeConstraint())
Visit(E);
if (const auto *TC = D->getPlaceholderTypeConstraint())
Visit(TC->getImmediatelyDeclaredConstraint());
if (D->hasDefaultArgument())
Visit(D->getDefaultArgument(), SourceRange(),
D->getDefaultArgStorage().getInheritedFrom(),
Expand Down
43 changes: 14 additions & 29 deletions clang/include/clang/AST/DeclTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -1102,17 +1102,6 @@ class FunctionTemplateDecl : public RedeclarableTemplateDecl {
/// template.
ArrayRef<TemplateArgument> getInjectedTemplateArgs();

/// Return whether this function template is an abbreviated function template,
/// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)`
bool isAbbreviated() const {
// Since the invented template parameters generated from 'auto' parameters
// are either appended to the end of the explicit template parameter list or
// form a new template paramter list, we can simply observe the last
// parameter to determine if such a thing happened.
const TemplateParameterList *TPL = getTemplateParameters();
return TPL->getParam(TPL->size() - 1)->isImplicit();
}

/// Merge \p Prev with our RedeclarableTemplateDecl::Common.
void mergePrevDecl(FunctionTemplateDecl *Prev);

Expand Down Expand Up @@ -1226,6 +1215,7 @@ class TemplateTypeParmDecl final : public TypeDecl,
bool ParameterPack,
bool HasTypeConstraint = false,
Optional<unsigned> NumExpanded = None);

static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
unsigned ID);
static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
Expand Down Expand Up @@ -1384,8 +1374,7 @@ class NonTypeTemplateParmDecl final
: public DeclaratorDecl,
protected TemplateParmPosition,
private llvm::TrailingObjects<NonTypeTemplateParmDecl,
std::pair<QualType, TypeSourceInfo *>,
Expr *> {
std::pair<QualType, TypeSourceInfo *>> {
friend class ASTDeclReader;
friend TrailingObjects;

Expand Down Expand Up @@ -1440,12 +1429,10 @@ class NonTypeTemplateParmDecl final
ArrayRef<TypeSourceInfo *> ExpandedTInfos);

static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
unsigned ID,
bool HasTypeConstraint);
unsigned ID);
static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
unsigned ID,
unsigned NumExpandedTypes,
bool HasTypeConstraint);
unsigned NumExpandedTypes);

using TemplateParmPosition::getDepth;
using TemplateParmPosition::setDepth;
Expand Down Expand Up @@ -1556,22 +1543,20 @@ class NonTypeTemplateParmDecl final
return TypesAndInfos[I].second;
}

/// Return the constraint introduced by the placeholder type of this non-type
/// Return the type-constraint in the placeholder type of this non-type
/// template parameter (if any).
Expr *getPlaceholderTypeConstraint() const {
return hasPlaceholderTypeConstraint() ? *getTrailingObjects<Expr *>() :
nullptr;
}

void setPlaceholderTypeConstraint(Expr *E) {
*getTrailingObjects<Expr *>() = E;
TypeConstraint *getPlaceholderTypeConstraint() const {
// TODO: Concepts: Implement once we have actual placeholders with type
// constraints.
return nullptr;
}

/// Determine whether this non-type template parameter's type has a
/// placeholder with a type-constraint.
bool hasPlaceholderTypeConstraint() const {
auto *AT = getType()->getContainedAutoType();
return AT && AT->isConstrained();
// TODO: Concepts: Implement once we have actual placeholders with type
// constraints.
return false;
}

/// \brief Get the associated-constraints of this template parameter.
Expand All @@ -1581,8 +1566,8 @@ class NonTypeTemplateParmDecl final
/// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for
/// concepts APIs that accept an ArrayRef of constraint expressions.
void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
if (Expr *E = getPlaceholderTypeConstraint())
AC.push_back(E);
if (TypeConstraint *TC = getPlaceholderTypeConstraint())
AC.push_back(TC->getImmediatelyDeclaredConstraint());
}

// Implement isa/cast/dyncast/etc.
Expand Down
2 changes: 0 additions & 2 deletions clang/include/clang/AST/PropertiesBase.td
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,6 @@ def DeclRef : RefPropertyType<"Decl"> { let ConstWhenWriting = 1; }
SubclassPropertyType<"TagDecl", DeclRef>;
def TemplateDeclRef :
SubclassPropertyType<"TemplateDecl", DeclRef>;
def ConceptDeclRef :
SubclassPropertyType<"ConceptDecl", DeclRef>;
def TemplateTypeParmDeclRef :
SubclassPropertyType<"TemplateTypeParmDecl", DeclRef>;
def TemplateTemplateParmDeclRef :
Expand Down
14 changes: 1 addition & 13 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -1040,13 +1040,7 @@ DEF_TRAVERSE_TYPE(UnaryTransformType, {
TRY_TO(TraverseType(T->getUnderlyingType()));
})

DEF_TRAVERSE_TYPE(AutoType, {
TRY_TO(TraverseType(T->getDeducedType()));
if (T->isConstrained()) {
TRY_TO(TraverseDecl(T->getTypeConstraintConcept()));
TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
}
})
DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
TRY_TO(TraverseTemplateName(T->getTemplateName()));
TRY_TO(TraverseType(T->getDeducedType()));
Expand Down Expand Up @@ -1293,12 +1287,6 @@ DEF_TRAVERSE_TYPELOC(UnaryTransformType, {

DEF_TRAVERSE_TYPELOC(AutoType, {
TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
if (TL.isConstrained()) {
TRY_TO(TraverseNestedNameSpecifierLoc(TL.getNestedNameSpecifierLoc()));
TRY_TO(TraverseDeclarationNameInfo(TL.getConceptNameInfo()));
for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
}
})

DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, {
Expand Down
7 changes: 1 addition & 6 deletions clang/include/clang/AST/TemplateBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ struct ASTTemplateArgumentListInfo final
}

static const ASTTemplateArgumentListInfo *
Create(const ASTContext &C, const TemplateArgumentListInfo &List);
Create(ASTContext &C, const TemplateArgumentListInfo &List);
};

/// Represents an explicit template argument list in C++, e.g.,
Expand Down Expand Up @@ -702,11 +702,6 @@ inline const TemplateArgument &
return getArgs()[Idx];
}

inline const TemplateArgument &AutoType::getArg(unsigned Idx) const {
assert(Idx < getNumArgs() && "Template argument out of range");
return getArgs()[Idx];
}

} // namespace clang

#endif // LLVM_CLANG_AST_TEMPLATEBASE_H
74 changes: 18 additions & 56 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ namespace clang {

class ExtQuals;
class QualType;
class ConceptDecl;
class TagDecl;
class Type;

Expand Down Expand Up @@ -1684,15 +1683,6 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
/// Was this placeholder type spelled as 'auto', 'decltype(auto)',
/// or '__auto_type'? AutoTypeKeyword value.
unsigned Keyword : 2;

/// The number of template arguments in the type-constraints, which is
/// expected to be able to hold at least 1024 according to [implimits].
/// However as this limit is somewhat easy to hit with template
/// metaprogramming we'd prefer to keep it as large as possible.
/// At the moment it has been left as a non-bitfield since this type
/// safely fits in 64 bits as an unsigned, so there is no reason to
/// introduce the performance impact of a bitfield.
unsigned NumArgs;
};

class SubstTemplateTypeParmPackTypeBitfields {
Expand Down Expand Up @@ -4824,7 +4814,8 @@ class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {

/// Common base class for placeholders for types that get replaced by
/// placeholder type deduction: C++11 auto, C++14 decltype(auto), C++17 deduced
/// class template types, and constrained type names.
/// class template types, and (eventually) constrained type names from the C++
/// Concepts TS.
///
/// These types are usually a placeholder for a deduced type. However, before
/// the initializer is attached, or (usually) if the initializer is
Expand Down Expand Up @@ -4869,50 +4860,18 @@ class DeducedType : public Type {
}
};

/// Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained
/// by a type-constraint.
class alignas(8) AutoType : public DeducedType, public llvm::FoldingSetNode {
/// Represents a C++11 auto or C++14 decltype(auto) type.
class AutoType : public DeducedType, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these

ConceptDecl *TypeConstraintConcept;

AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword,
bool IsDeducedAsDependent, bool IsDeducedAsPack, ConceptDecl *CD,
ArrayRef<TemplateArgument> TypeConstraintArgs);

const TemplateArgument *getArgBuffer() const {
return reinterpret_cast<const TemplateArgument*>(this+1);
}

TemplateArgument *getArgBuffer() {
return reinterpret_cast<TemplateArgument*>(this+1);
bool IsDeducedAsDependent, bool IsDeducedAsPack)
: DeducedType(Auto, DeducedAsType, IsDeducedAsDependent,
IsDeducedAsDependent, IsDeducedAsPack) {
AutoTypeBits.Keyword = (unsigned)Keyword;
}

public:
/// Retrieve the template arguments.
const TemplateArgument *getArgs() const {
return getArgBuffer();
}

/// Retrieve the number of template arguments.
unsigned getNumArgs() const {
return AutoTypeBits.NumArgs;
}

const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h

ArrayRef<TemplateArgument> getTypeConstraintArguments() const {
return {getArgs(), getNumArgs()};
}

ConceptDecl *getTypeConstraintConcept() const {
return TypeConstraintConcept;
}

bool isConstrained() const {
return TypeConstraintConcept != nullptr;
}

bool isDecltypeAuto() const {
return getKeyword() == AutoTypeKeyword::DecltypeAuto;
}
Expand All @@ -4921,15 +4880,18 @@ class alignas(8) AutoType : public DeducedType, public llvm::FoldingSetNode {
return (AutoTypeKeyword)AutoTypeBits.Keyword;
}

void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
Profile(ID, Context, getDeducedType(), getKeyword(), isDependentType(),
getTypeConstraintConcept(), getTypeConstraintArguments());
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getDeducedType(), getKeyword(), isDependentType(),
containsUnexpandedParameterPack());
}

static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
QualType Deduced, AutoTypeKeyword Keyword,
bool IsDependent, ConceptDecl *CD,
ArrayRef<TemplateArgument> Arguments);
static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced,
AutoTypeKeyword Keyword, bool IsDependent, bool IsPack) {
ID.AddPointer(Deduced.getAsOpaquePtr());
ID.AddInteger((unsigned)Keyword);
ID.AddBoolean(IsDependent);
ID.AddBoolean(IsPack);
}

static bool classof(const Type *T) {
return T->getTypeClass() == Auto;
Expand Down
Loading

0 comments on commit 5c02fe1

Please sign in to comment.