Skip to content

Commit 2d6829b

Browse files
committed
[clang] disable implicit moves when not in CPlusPLus
See PR51842. This fixes an assert firing in the static analyzer, triggered by implicit moves in blocks in C mode: This also simplifies the AST a little bit when compiling non C++ code, as the xvalue implicit casts are not inserted. We keep and test that the nrvo flag is still being set on the VarDecls, as that is still a bit beneficial while not really making anything more complicated. Signed-off-by: Matheus Izvekov <[email protected]> Reviewed By: NoQ Differential Revision: https://reviews.llvm.org/D109654
1 parent f287405 commit 2d6829b

File tree

3 files changed

+45
-1
lines changed

3 files changed

+45
-1
lines changed

clang/lib/Sema/SemaStmt.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3481,7 +3481,8 @@ VerifyInitializationSequenceCXX98(const Sema &S,
34813481
ExprResult Sema::PerformMoveOrCopyInitialization(
34823482
const InitializedEntity &Entity, const NamedReturnInfo &NRInfo, Expr *Value,
34833483
bool SupressSimplerImplicitMoves) {
3484-
if ((!getLangOpts().CPlusPlus2b || SupressSimplerImplicitMoves) &&
3484+
if (getLangOpts().CPlusPlus &&
3485+
(!getLangOpts().CPlusPlus2b || SupressSimplerImplicitMoves) &&
34853486
NRInfo.isMoveEligible()) {
34863487
ImplicitCastExpr AsRvalue(ImplicitCastExpr::OnStack, Value->getType(),
34873488
CK_NoOp, Value, VK_XValue, FPOptionsOverride());

clang/test/AST/nrvo.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %clang_cc1 -ast-dump -fblocks %s | FileCheck -strict-whitespace %s
2+
3+
struct A {};
4+
5+
struct A f1() {
6+
// CHECK: FunctionDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:{{[^:]*}}:1> line:[[@LINE-1]]:10 f1 'struct A ()'
7+
// CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:15, line:{{[^:]*}}:1>
8+
struct A a;
9+
// CHECK-NEXT: DeclStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:13>
10+
// CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:3, col:12> col:12 used a 'struct A':'struct A' nrvo
11+
return a;
12+
// CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:10>
13+
// CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}} <col:10> 'struct A':'struct A' <LValueToRValue>
14+
// CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:10> 'struct A':'struct A' lvalue Var 0x{{[^ ]*}} 'a' 'struct A':'struct A'
15+
}
16+
17+
void f2() {
18+
(void)^{
19+
// CHECK: BlockDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:9, line:{{[^:]*}}:3> line:[[@LINE-1]]:9
20+
// CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:10, line:{{[^:]*}}:3>
21+
struct A a;
22+
// CHECK-NEXT: DeclStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:15>
23+
// CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:5, col:14> col:14 used a 'struct A':'struct A' nrvo
24+
return a;
25+
// CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:12>
26+
// CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}} <col:12> 'struct A':'struct A' <LValueToRValue>
27+
// CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:12> 'struct A':'struct A' lvalue Var 0x{{[^ ]*}} 'a' 'struct A':'struct A'
28+
}();
29+
}

clang/test/Analysis/blocks-nrvo.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %clang_analyze_cc1 -w -analyzer-checker=core -fblocks -verify %s
2+
3+
// expected-no-diagnostics
4+
5+
typedef struct {
6+
int x;
7+
} S;
8+
9+
void foo() {
10+
^{
11+
S s;
12+
return s; // no-crash
13+
};
14+
}

0 commit comments

Comments
 (0)