Skip to content

Commit

Permalink
Revert "Implement CWG2631"
Browse files Browse the repository at this point in the history
This reverts commit 7acfe36.
This reverts commit 5f87a89.
This reverts commit 6875ac6.
  • Loading branch information
cor3ntin committed Nov 4, 2022
1 parent 52ffc72 commit 35a870c
Show file tree
Hide file tree
Showing 22 changed files with 146 additions and 788 deletions.
5 changes: 0 additions & 5 deletions clang/docs/ReleaseNotes.rst
Expand Up @@ -578,11 +578,6 @@ C++ Language Changes in Clang
conforming GNU extensions. Projects incompatible with C++17 can add
``-std=gnu++14`` to their build settings to restore the previous behaviour.
- Implemented DR2358 allowing init captures in lambdas in default arguments.
- Implemented DR2631. Invalid ``consteval`` calls in default arguments and default
member initializers are diagnosed when and if the default is used.
This Fixes `Issue 56379 <https://github.com/llvm/llvm-project/issues/56379>`_
and changes the value of ``std::source_location::current()``
used in default parameters calls compared to previous versions of Clang.

C++20 Feature Support
^^^^^^^^^^^^^^^^^^^^^
Expand Down
108 changes: 24 additions & 84 deletions clang/include/clang/AST/ExprCXX.h
Expand Up @@ -1245,12 +1245,8 @@ class CXXThrowExpr : public Expr {
/// This wraps up a function call argument that was created from the
/// corresponding parameter's default argument, when the call did not
/// explicitly supply arguments for all of the parameters.
class CXXDefaultArgExpr final
: public Expr,
private llvm::TrailingObjects<CXXDefaultArgExpr, Expr *> {
class CXXDefaultArgExpr final : public Expr {
friend class ASTStmtReader;
friend class ASTReader;
friend TrailingObjects;

/// The parameter whose default is being used.
ParmVarDecl *Param;
Expand All @@ -1259,7 +1255,7 @@ class CXXDefaultArgExpr final
DeclContext *UsedContext;

CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param,
Expr *RewrittenExpr, DeclContext *UsedContext)
DeclContext *UsedContext)
: Expr(SC,
Param->hasUnparsedDefaultArg()
? Param->getType().getNonReferenceType()
Expand All @@ -1268,58 +1264,28 @@ class CXXDefaultArgExpr final
Param->getDefaultArg()->getObjectKind()),
Param(Param), UsedContext(UsedContext) {
CXXDefaultArgExprBits.Loc = Loc;
CXXDefaultArgExprBits.HasRewrittenInit = RewrittenExpr != nullptr;
if (RewrittenExpr)
*getTrailingObjects<Expr *>() = RewrittenExpr;
setDependence(computeDependence(this));
}

CXXDefaultArgExpr(EmptyShell Empty, bool HasRewrittenInit)
: Expr(CXXDefaultArgExprClass, Empty) {
CXXDefaultArgExprBits.HasRewrittenInit = HasRewrittenInit;
}

size_t numTrailingObjects() const {
return CXXDefaultArgExprBits.HasRewrittenInit;
}

public:
static CXXDefaultArgExpr *CreateEmpty(const ASTContext &C,
bool HasRewrittenInit);
CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {}

// \p Param is the parameter whose default argument is used by this
// expression.
static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc,
ParmVarDecl *Param, Expr *RewrittenExpr,
DeclContext *UsedContext);
ParmVarDecl *Param,
DeclContext *UsedContext) {
return new (C)
CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param, UsedContext);
}

// Retrieve the parameter that the argument was created from.
const ParmVarDecl *getParam() const { return Param; }
ParmVarDecl *getParam() { return Param; }

bool hasRewrittenInit() const {
return CXXDefaultArgExprBits.HasRewrittenInit;
}

// Retrieve the argument to the function call.
Expr *getExpr();
const Expr *getExpr() const {
return const_cast<CXXDefaultArgExpr *>(this)->getExpr();
}

Expr *getRewrittenExpr() {
return hasRewrittenInit() ? *getTrailingObjects<Expr *>() : nullptr;
}

const Expr *getRewrittenExpr() const {
return const_cast<CXXDefaultArgExpr *>(this)->getRewrittenExpr();
}

// Retrieve the rewritten init expression (for an init expression containing
// immediate calls) with the top level FullExpr and ConstantExpr stripped off.
Expr *getAdjustedRewrittenExpr();
const Expr *getAdjustedRewrittenExpr() const {
return const_cast<CXXDefaultArgExpr *>(this)->getAdjustedRewrittenExpr();
}
// Retrieve the actual argument to the function call.
const Expr *getExpr() const { return getParam()->getDefaultArg(); }
Expr *getExpr() { return getParam()->getDefaultArg(); }

const DeclContext *getUsedContext() const { return UsedContext; }
DeclContext *getUsedContext() { return UsedContext; }
Expand Down Expand Up @@ -1356,67 +1322,41 @@ class CXXDefaultArgExpr final
/// is implicitly used in a mem-initializer-list in a constructor
/// (C++11 [class.base.init]p8) or in aggregate initialization
/// (C++1y [dcl.init.aggr]p7).
class CXXDefaultInitExpr final
: public Expr,
private llvm::TrailingObjects<CXXDefaultArgExpr, Expr *> {

friend class ASTStmtReader;
class CXXDefaultInitExpr : public Expr {
friend class ASTReader;
friend TrailingObjects;
friend class ASTStmtReader;

/// The field whose default is being used.
FieldDecl *Field;

/// The context where the default initializer expression was used.
DeclContext *UsedContext;

CXXDefaultInitExpr(const ASTContext &Ctx, SourceLocation Loc,
FieldDecl *Field, QualType Ty, DeclContext *UsedContext,
Expr *RewrittenInitExpr);

CXXDefaultInitExpr(EmptyShell Empty, bool HasRewrittenInit)
: Expr(CXXDefaultInitExprClass, Empty) {
CXXDefaultInitExprBits.HasRewrittenInit = HasRewrittenInit;
}
FieldDecl *Field, QualType Ty, DeclContext *UsedContext);

size_t numTrailingObjects() const {
return CXXDefaultInitExprBits.HasRewrittenInit;
}
CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {}

public:
static CXXDefaultInitExpr *CreateEmpty(const ASTContext &C,
bool HasRewrittenInit);
/// \p Field is the non-static data member whose default initializer is used
/// by this expression.
static CXXDefaultInitExpr *Create(const ASTContext &Ctx, SourceLocation Loc,
FieldDecl *Field, DeclContext *UsedContext,
Expr *RewrittenInitExpr);

bool hasRewrittenInit() const {
return CXXDefaultInitExprBits.HasRewrittenInit;
FieldDecl *Field, DeclContext *UsedContext) {
return new (Ctx) CXXDefaultInitExpr(Ctx, Loc, Field, Field->getType(), UsedContext);
}

/// Get the field whose initializer will be used.
FieldDecl *getField() { return Field; }
const FieldDecl *getField() const { return Field; }

/// Get the initialization expression that will be used.
Expr *getExpr();
const Expr *getExpr() const {
return const_cast<CXXDefaultInitExpr *>(this)->getExpr();
}

/// Retrieve the initializing expression with evaluated immediate calls, if
/// any.
const Expr *getRewrittenExpr() const {
assert(hasRewrittenInit() && "expected a rewritten init expression");
return *getTrailingObjects<Expr *>();
assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
return Field->getInClassInitializer();
}

/// Retrieve the initializing expression with evaluated immediate calls, if
/// any.
Expr *getRewrittenExpr() {
assert(hasRewrittenInit() && "expected a rewritten init expression");
return *getTrailingObjects<Expr *>();
Expr *getExpr() {
assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
return Field->getInClassInitializer();
}

const DeclContext *getUsedContext() const { return UsedContext; }
Expand Down
7 changes: 0 additions & 7 deletions clang/include/clang/AST/Stmt.h
Expand Up @@ -686,9 +686,6 @@ class alignas(void *) Stmt {

unsigned : NumExprBits;

/// Whether this CXXDefaultArgExpr rewrote its argument and stores a copy.
unsigned HasRewrittenInit : 1;

/// The location where the default argument expression was used.
SourceLocation Loc;
};
Expand All @@ -699,10 +696,6 @@ class alignas(void *) Stmt {

unsigned : NumExprBits;

/// Whether this CXXDefaultInitExprBitfields rewrote its argument and stores
/// a copy.
unsigned HasRewrittenInit : 1;

/// The location where the default initializer expression was used.
SourceLocation Loc;
};
Expand Down
4 changes: 0 additions & 4 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Expand Up @@ -2644,10 +2644,6 @@ def err_invalid_consteval_take_address : Error<
" of an immediate invocation">;
def err_invalid_consteval_call : Error<
"call to consteval function %q0 is not a constant expression">;
def note_invalid_consteval_initializer : Note<
"in the default initalizer of %0">;
def note_invalid_consteval_initializer_here : Note<
"initialized here %0">;
def err_invalid_consteval_decl_kind : Error<
"%0 cannot be declared consteval">;
def err_invalid_constexpr : Error<
Expand Down
87 changes: 4 additions & 83 deletions clang/include/clang/Sema/Sema.h
Expand Up @@ -1330,25 +1330,6 @@ class Sema final {
bool InDiscardedStatement;
bool InImmediateFunctionContext;

bool IsCurrentlyCheckingDefaultArgumentOrInitializer = false;

// When evaluating immediate functions in the initializer of a default
// argument or default member initializer, this is the declaration whose
// default initializer is being evaluated and the location of the call
// or constructor definition.
struct InitializationContext {
InitializationContext(SourceLocation Loc, ValueDecl *Decl,
DeclContext *Context)
: Loc(Loc), Decl(Decl), Context(Context) {
assert(Decl && Context && "invalid initialization context");
};

SourceLocation Loc;
ValueDecl *Decl = nullptr;
DeclContext *Context = nullptr;
};
llvm::Optional<InitializationContext> DelayedDefaultInitializationContext;

ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,
unsigned NumCleanupObjects,
CleanupInfo ParentCleanup,
Expand Down Expand Up @@ -6215,22 +6196,19 @@ class Sema final {
bool IsStdInitListInitialization, bool RequiresZeroInit,
unsigned ConstructKind, SourceRange ParenRange);

ExprResult ConvertMemberDefaultInitExpression(FieldDecl *FD, Expr *InitExpr,
SourceLocation InitLoc);

ExprResult BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field);


/// Instantiate or parse a C++ default argument expression as necessary.
/// Return true on error.
bool CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
ParmVarDecl *Param, Expr *Init = nullptr,
bool SkipImmediateInvocations = true);
ParmVarDecl *Param);

/// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
/// the default expr if needed.
ExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
ParmVarDecl *Param, Expr *Init = nullptr);
ExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc,
FunctionDecl *FD,
ParmVarDecl *Param);

/// FinalizeVarWithDestructor - Prepare for calling destructor on the
/// constructed variable.
Expand Down Expand Up @@ -9634,63 +9612,6 @@ class Sema final {
return ExprEvalContexts.back().isImmediateFunctionContext();
}

bool isCheckingDefaultArgumentOrInitializer() const {
assert(!ExprEvalContexts.empty() &&
"Must be in an expression evaluation context");
const ExpressionEvaluationContextRecord &Ctx = ExprEvalContexts.back();
return (Ctx.Context ==
ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed) ||
Ctx.IsCurrentlyCheckingDefaultArgumentOrInitializer;
}

bool isCheckingDefaultArgumentOrInitializerOfOuterEntity() const {
assert(!ExprEvalContexts.empty() &&
"Must be in an expression evaluation context");
for (const auto &Ctx : llvm::reverse(ExprEvalContexts)) {
if ((Ctx.Context ==
ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed) ||
Ctx.IsCurrentlyCheckingDefaultArgumentOrInitializer)
return true;
if (Ctx.isConstantEvaluated() || Ctx.isImmediateFunctionContext() ||
Ctx.isUnevaluated())
return false;
}
return false;
}

llvm::Optional<ExpressionEvaluationContextRecord::InitializationContext>
InnermostDeclarationWithDelayedImmediateInvocations() const {
assert(!ExprEvalContexts.empty() &&
"Must be in an expression evaluation context");
for (const auto &Ctx : llvm::reverse(ExprEvalContexts)) {
if (Ctx.Context == ExpressionEvaluationContext::PotentiallyEvaluated &&
Ctx.DelayedDefaultInitializationContext)
return Ctx.DelayedDefaultInitializationContext;
if (Ctx.isConstantEvaluated() || Ctx.isImmediateFunctionContext() ||
Ctx.isUnevaluated())
break;
}
return llvm::None;
}

llvm::Optional<ExpressionEvaluationContextRecord::InitializationContext>
OutermostDeclarationWithDelayedImmediateInvocations() const {
assert(!ExprEvalContexts.empty() &&
"Must be in an expression evaluation context");
llvm::Optional<ExpressionEvaluationContextRecord::InitializationContext>
Res;
for (auto &Ctx : llvm::reverse(ExprEvalContexts)) {
if (Ctx.Context == ExpressionEvaluationContext::PotentiallyEvaluated &&
!Ctx.DelayedDefaultInitializationContext && Res)
break;
if (Ctx.isConstantEvaluated() || Ctx.isImmediateFunctionContext() ||
Ctx.isUnevaluated())
break;
Res = Ctx.DelayedDefaultInitializationContext;
}
return Res;
}

/// RAII class used to determine whether SFINAE has
/// trapped any errors that occur during template argument
/// deduction.
Expand Down
21 changes: 3 additions & 18 deletions clang/lib/AST/ASTImporter.cpp
Expand Up @@ -7687,16 +7687,9 @@ ExpectedStmt ASTNodeImporter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
if (Error Err = ImportDefaultArgOfParmVarDecl(*FromParam, ToParam))
return std::move(Err);
}
Expr *RewrittenInit = nullptr;
if (E->hasRewrittenInit()) {
ExpectedExpr ExprOrErr = import(E->getExpr());
if (!ExprOrErr)
return ExprOrErr.takeError();
RewrittenInit = ExprOrErr.get();
}

return CXXDefaultArgExpr::Create(Importer.getToContext(), *ToUsedLocOrErr,
*ToParamOrErr, RewrittenInit,
*UsedContextOrErr);
*ToParamOrErr, *UsedContextOrErr);
}

ExpectedStmt
Expand Down Expand Up @@ -8388,16 +8381,8 @@ ExpectedStmt ASTNodeImporter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
ToField->setInClassInitializer(*ToInClassInitializerOrErr);
}

Expr *RewrittenInit = nullptr;
if (E->hasRewrittenInit()) {
ExpectedExpr ExprOrErr = import(E->getExpr());
if (!ExprOrErr)
return ExprOrErr.takeError();
RewrittenInit = ExprOrErr.get();
}

return CXXDefaultInitExpr::Create(Importer.getToContext(), *ToBeginLocOrErr,
ToField, *UsedContextOrErr, RewrittenInit);
ToField, *UsedContextOrErr);
}

ExpectedStmt ASTNodeImporter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/AST/Decl.cpp
Expand Up @@ -2889,7 +2889,8 @@ Expr *ParmVarDecl::getDefaultArg() {

Expr *Arg = getInit();
if (auto *E = dyn_cast_or_null<FullExpr>(Arg))
return E->getSubExpr();
if (!isa<ConstantExpr>(E))
return E->getSubExpr();

return Arg;
}
Expand Down

0 comments on commit 35a870c

Please sign in to comment.