mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-24 15:06:06 +00:00
[clang] Allow consteval functions in default arguments
We should not mark a function as "referenced" if we call it within a ConstantExpr, because the expression will be folded to a value in LLVM IR. To prevent emitting consteval function declarations, we should not "jump over" a ConstantExpr when it is a top-level ParmVarDecl's subexpression. Fixes https://github.com/llvm/llvm-project/issues/48230 Reviewed By: erichkeane, aaron.ballman, ChuanqiXu Differenitial Revision: https://reviews.llvm.org/D119646
This commit is contained in:
parent
f9ac557567
commit
a4f8590247
@ -166,6 +166,8 @@ Bug Fixes
|
||||
- Allow use of an elaborated type specifier as a ``_Generic`` selection
|
||||
association in C++ mode. This fixes
|
||||
`Issue 55562 <https://github.com/llvm/llvm-project/issues/55562>`_.
|
||||
- Clang will allow calling a ``consteval`` function in a default argument. This
|
||||
fixes `Issue 48230 <https://github.com/llvm/llvm-project/issues/48230>`_.
|
||||
|
||||
Improvements to Clang's diagnostics
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -2867,7 +2867,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;
|
||||
}
|
||||
|
@ -19611,6 +19611,12 @@ public:
|
||||
Inherited::Visit(E);
|
||||
}
|
||||
|
||||
void VisitConstantExpr(ConstantExpr *E) {
|
||||
// Don't mark declarations within a ConstantExpression, as this expression
|
||||
// will be evaluated and folded to a value.
|
||||
return;
|
||||
}
|
||||
|
||||
void VisitDeclRefExpr(DeclRefExpr *E) {
|
||||
// If we were asked not to visit local variables, don't.
|
||||
if (SkipLocalVariables) {
|
||||
|
@ -651,6 +651,27 @@ static_assert(baz<int>() == sizeof(int));
|
||||
|
||||
} // namespace value_dependent
|
||||
|
||||
namespace default_argument {
|
||||
|
||||
// Previously calls of consteval functions in default arguments were rejected.
|
||||
// Now we show that we don't reject such calls.
|
||||
consteval int foo() { return 1; }
|
||||
consteval int bar(int i = foo()) { return i * i; }
|
||||
|
||||
struct Test1 {
|
||||
Test1(int i = bar(13)) {}
|
||||
void v(int i = bar(13) * 2 + bar(15)) {}
|
||||
};
|
||||
Test1 t1;
|
||||
|
||||
struct Test2 {
|
||||
constexpr Test2(int i = bar()) {}
|
||||
constexpr void v(int i = bar(bar(bar(foo())))) {}
|
||||
};
|
||||
Test2 t2;
|
||||
|
||||
} // namespace default_argument
|
||||
|
||||
namespace PR50779 {
|
||||
struct derp {
|
||||
int b = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user