[Clang] Only check exprs that might be immediate escalating in evaluated contexts (#93187)

As per https://eel.is/c++draft/expr.const#17

Fixes #91308

---------

Co-authored-by: Mariya Podchishchaeva <mariya.podchishchaeva@intel.com>
This commit is contained in:
cor3ntin 2024-05-23 17:53:07 +02:00 committed by GitHub
parent 5a81db311c
commit dd32c3d36f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 28 additions and 0 deletions

View File

@ -769,6 +769,8 @@ Bug Fixes to C++ Support
- Fixed a crash when trying to emit captures in a lambda call operator with an explicit object
parameter that is called on a derived type of the lambda.
Fixes (#GH87210), (GH89541).
- Clang no longer tries to check if an expression is immediate-escalating in an unevaluated context.
Fixes (#GH91308).
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -5112,6 +5112,13 @@ public:
Context == ExpressionEvaluationContext::UnevaluatedList;
}
bool isPotentiallyEvaluated() const {
return Context == ExpressionEvaluationContext::PotentiallyEvaluated ||
Context ==
ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed ||
Context == ExpressionEvaluationContext::ConstantEvaluated;
}
bool isConstantEvaluated() const {
return Context == ExpressionEvaluationContext::ConstantEvaluated ||
Context == ExpressionEvaluationContext::ImmediateFunctionContext;
@ -5146,6 +5153,12 @@ public:
return ExprEvalContexts.back();
};
const ExpressionEvaluationContextRecord &parentEvaluationContext() const {
assert(ExprEvalContexts.size() >= 2 &&
"Must be in an expression evaluation context");
return ExprEvalContexts[ExprEvalContexts.size() - 2];
};
bool isBoundsAttrContext() const {
return ExprEvalContexts.back().ExprContext ==
ExpressionEvaluationContextRecord::ExpressionKind::

View File

@ -4788,8 +4788,13 @@ TemplateDeductionResult Sema::DeduceTemplateArguments(
DeduceReturnType(Specialization, Info.getLocation(), false))
return TemplateDeductionResult::MiscellaneousDeductionFailure;
// [C++26][expr.const]/p17
// An expression or conversion is immediate-escalating if it is not initially
// in an immediate function context and it is [...]
// a potentially-evaluated id-expression that denotes an immediate function.
if (IsAddressOfFunction && getLangOpts().CPlusPlus20 &&
Specialization->isImmediateEscalating() &&
parentEvaluationContext().isPotentiallyEvaluated() &&
CheckIfFunctionSpecializationIsImmediate(Specialization,
Info.getLocation()))
return TemplateDeductionResult::MiscellaneousDeductionFailure;

View File

@ -446,3 +446,11 @@ int h(int x) {
}
#endif
namespace GH91308 {
constexpr void f(auto) {
static_assert(false);
}
using R1 = decltype(&f<int>);
}