summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatheus Izvekov <mizvekov@gmail.com>2021-09-12 01:11:02 +0200
committerTom Stellard <tstellar@redhat.com>2021-09-17 10:13:15 -0700
commit89f2c0c63c220fd5aa36279401a5cb883dfbbc34 (patch)
tree0c7fe98c12ae3bd7636677a10d1d008c0c99a8a9
parent[clang-repl] Install clang-repl (diff)
downloadllvm-project-89f2c0c63c220fd5aa36279401a5cb883dfbbc34.tar.gz
llvm-project-89f2c0c63c220fd5aa36279401a5cb883dfbbc34.tar.bz2
llvm-project-89f2c0c63c220fd5aa36279401a5cb883dfbbc34.zip
[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 <mizvekov@gmail.com> Reviewed By: NoQ Differential Revision: https://reviews.llvm.org/D109654 (cherry picked from commit 2d6829bbbe6877920d9be1db93b9f3fc85b43d10)
-rw-r--r--clang/lib/Sema/SemaStmt.cpp3
-rw-r--r--clang/test/AST/nrvo.c29
-rw-r--r--clang/test/Analysis/blocks-nrvo.c14
3 files changed, 45 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 3baccec2d7bb..f7e4110e6110 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3481,7 +3481,8 @@ VerifyInitializationSequenceCXX98(const Sema &S,
ExprResult Sema::PerformMoveOrCopyInitialization(
const InitializedEntity &Entity, const NamedReturnInfo &NRInfo, Expr *Value,
bool SupressSimplerImplicitMoves) {
- if ((!getLangOpts().CPlusPlus2b || SupressSimplerImplicitMoves) &&
+ if (getLangOpts().CPlusPlus &&
+ (!getLangOpts().CPlusPlus2b || SupressSimplerImplicitMoves) &&
NRInfo.isMoveEligible()) {
ImplicitCastExpr AsRvalue(ImplicitCastExpr::OnStack, Value->getType(),
CK_NoOp, Value, VK_XValue, FPOptionsOverride());
diff --git a/clang/test/AST/nrvo.c b/clang/test/AST/nrvo.c
new file mode 100644
index 000000000000..4f50d6a1e384
--- /dev/null
+++ b/clang/test/AST/nrvo.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -ast-dump -fblocks %s | FileCheck -strict-whitespace %s
+
+struct A {};
+
+struct A f1() {
+ // CHECK: FunctionDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:{{[^:]*}}:1> line:[[@LINE-1]]:10 f1 'struct A ()'
+ // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:15, line:{{[^:]*}}:1>
+ struct A a;
+ // CHECK-NEXT: DeclStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:13>
+ // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:3, col:12> col:12 used a 'struct A':'struct A' nrvo
+ return a;
+ // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:10>
+ // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}} <col:10> 'struct A':'struct A' <LValueToRValue>
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:10> 'struct A':'struct A' lvalue Var 0x{{[^ ]*}} 'a' 'struct A':'struct A'
+}
+
+void f2() {
+ (void)^{
+ // CHECK: BlockDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:9, line:{{[^:]*}}:3> line:[[@LINE-1]]:9
+ // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:10, line:{{[^:]*}}:3>
+ struct A a;
+ // CHECK-NEXT: DeclStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:15>
+ // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:5, col:14> col:14 used a 'struct A':'struct A' nrvo
+ return a;
+ // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:12>
+ // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}} <col:12> 'struct A':'struct A' <LValueToRValue>
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:12> 'struct A':'struct A' lvalue Var 0x{{[^ ]*}} 'a' 'struct A':'struct A'
+ }();
+}
diff --git a/clang/test/Analysis/blocks-nrvo.c b/clang/test/Analysis/blocks-nrvo.c
new file mode 100644
index 000000000000..bb0be869ee76
--- /dev/null
+++ b/clang/test/Analysis/blocks-nrvo.c
@@ -0,0 +1,14 @@
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core -fblocks -verify %s
+
+// expected-no-diagnostics
+
+typedef struct {
+ int x;
+} S;
+
+void foo() {
+ ^{
+ S s;
+ return s; // no-crash
+ };
+}