[PATCH] D136554: Implement CWG2631
Aaron Ballman via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 1 06:05:01 PDT 2022
aaron.ballman added inline comments.
================
Comment at: clang/include/clang/Sema/Sema.h:9602-9604
+ return Ctx.Context ==
+ ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed ||
+ Ctx.IsCheckingDefaultArgumentOrInitializer;
----------------
Hmm, it'd be nice to not name this with the same identifier as the `bool` member on line 1333, that surprised me a little bit when I ran into it below.
================
Comment at: clang/include/clang/Sema/Sema.h:9610
+ "Must be in an expression evaluation context");
+ for (auto &Ctx : llvm::reverse(ExprEvalContexts)) {
+ if (Ctx.Context ==
----------------
================
Comment at: clang/include/clang/Sema/Sema.h:9628
+ if (Ctx.Context == ExpressionEvaluationContext::PotentiallyEvaluated &&
+ Ctx.DelayedDefaultInitializationContext.has_value())
+ return Ctx.DelayedDefaultInitializationContext;
----------------
================
Comment at: clang/include/clang/Sema/Sema.h:9645-9646
+ if (Ctx.Context == ExpressionEvaluationContext::PotentiallyEvaluated &&
+ !Ctx.DelayedDefaultInitializationContext.has_value() &&
+ Res.has_value())
+ break;
----------------
================
Comment at: clang/lib/AST/ExprCXX.cpp:964
+ DeclContext *UsedContext) {
+ size_t Size = totalSizeToAlloc<Expr *>(RewrittenExpr != nullptr ? 1 : 0);
+ auto *Mem = C.Allocate(Size, alignof(CXXDefaultArgExpr));
----------------
================
Comment at: clang/lib/AST/ExprCXX.cpp:1019
+
+ size_t Size = totalSizeToAlloc<Expr *>(RewrittenInitExpr != nullptr ? 1 : 0);
+ auto *Mem = Ctx.Allocate(Size, alignof(CXXDefaultArgExpr));
----------------
================
Comment at: clang/lib/Sema/SemaExpr.cpp:5927
+ bool VisitSourceLocExpr(SourceLocExpr *E) {
+ HasImmediateCalls = true;
+ return RecursiveASTVisitor<ImmediateCallVisitor>::VisitStmt(E);
----------------
It may be worth a comment that this relies on the behavior of `VisitLambdaExpr` not changing to visit the lambda body. Otherwise, nested invocations would be an issue in something like `void func(int a = []{ return std::source_location::current(); }());` because we'd claim there is an immediate call for that default arg expression when there isn't one.
As it stands, I wonder what the behavior of this code should be:
```
void func(int a =
({
int val = std::souce_location::current();
val;
})
);
```
(Oh, wait, I know, I think we made that code invalid because GNU statement expressions in a default argument are horrifying...)
Also, it looks like this code ignores blocks while handling lambdas; shouldn't blocks be handled the same way as lambdas?
Can you also add a test for this example:
```
void func(int a =
(int){ std::source_location::current() }
);
```
and I suppose we also should have a test for:
```
consteval int terrible_idea_dont_write_this_code_please(
int &out,
const int (&a)[std::source_location::current()] = { std::source_location::current() }
) { out = a[0]; return sizeof(a); }
consteval void func() {
int a;
static_assert(terrible_idea_dont_write_this_code_please(a) == a, "hahaha, not a chance!");
}
```
which demonstrates just how deeply bizarre WG21's decision is here -- the returned value != `out`.
And similar tests for default inits.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D136554/new/
https://reviews.llvm.org/D136554
More information about the cfe-commits
mailing list