|
17 | 17 | #include "clang/AST/Decl.h" |
18 | 18 | #include "clang/AST/DeclCXX.h" |
19 | 19 | #include "clang/AST/Expr.h" |
| 20 | +#include "clang/AST/Stmt.h" |
20 | 21 | #include "clang/AST/Type.h" |
21 | 22 | #include "clang/Basic/SourceLocation.h" |
22 | 23 | #include "clang/Basic/Specifiers.h" |
@@ -48,6 +49,14 @@ static FunctionDecl *lookupBuiltinFunction(Sema &S, StringRef Name) { |
48 | 49 | "Since this is a builtin it should always resolve!"); |
49 | 50 | return cast<FunctionDecl>(R.getFoundDecl()); |
50 | 51 | } |
| 52 | + |
| 53 | +CXXConstructorDecl *lookupCopyConstructor(QualType ResTy) { |
| 54 | + assert(ResTy->isRecordType() && "not a CXXRecord type"); |
| 55 | + for (auto *CD : ResTy->getAsCXXRecordDecl()->ctors()) |
| 56 | + if (CD->isCopyConstructor()) |
| 57 | + return CD; |
| 58 | + return nullptr; |
| 59 | +} |
51 | 60 | } // namespace |
52 | 61 |
|
53 | 62 | // Builder for template arguments of builtin types. Used internally |
@@ -580,6 +589,23 @@ BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::returnValue(T ReturnValue) { |
580 | 589 |
|
581 | 590 | Expr *ReturnValueExpr = convertPlaceholder(ReturnValue); |
582 | 591 | ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); |
| 592 | + |
| 593 | + QualType Ty = ReturnValueExpr->getType(); |
| 594 | + if (Ty->isRecordType()) { |
| 595 | + // For record types, create a call to copy constructor to ensure proper copy |
| 596 | + // semantics. |
| 597 | + auto *ICE = |
| 598 | + ImplicitCastExpr::Create(AST, Ty.withConst(), CK_NoOp, ReturnValueExpr, |
| 599 | + nullptr, VK_XValue, FPOptionsOverride()); |
| 600 | + CXXConstructorDecl *CD = lookupCopyConstructor(Ty); |
| 601 | + assert(CD && "no copy constructor found"); |
| 602 | + ReturnValueExpr = CXXConstructExpr::Create( |
| 603 | + AST, Ty, SourceLocation(), CD, /*Elidable=*/false, {ICE}, |
| 604 | + /*HadMultipleCandidates=*/false, /*ListInitialization=*/false, |
| 605 | + /*StdInitListInitialization=*/false, |
| 606 | + /*ZeroInitListInitialization=*/false, CXXConstructionKind::Complete, |
| 607 | + SourceRange()); |
| 608 | + } |
583 | 609 | StmtsList.push_back( |
584 | 610 | ReturnStmt::Create(AST, SourceLocation(), ReturnValueExpr, nullptr)); |
585 | 611 | return *this; |
|
0 commit comments