diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -3481,7 +3481,8 @@ 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 --- /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]]:10 f1 'struct A ()' + // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} + struct A a; + // CHECK-NEXT: DeclStmt 0x{{[^ ]*}} + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} col:12 used a 'struct A':'struct A' nrvo + return a; + // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} + // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}} 'struct A':'struct A' + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} 'struct A':'struct A' lvalue Var 0x{{[^ ]*}} 'a' 'struct A':'struct A' +} + +void f2() { + (void)^{ + // CHECK: BlockDecl 0x{{[^ ]*}} line:[[@LINE-1]]:9 + // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} + struct A a; + // CHECK-NEXT: DeclStmt 0x{{[^ ]*}} + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} col:14 used a 'struct A':'struct A' nrvo + return a; + // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} + // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}} 'struct A':'struct A' + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} '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 --- /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 + }; +}