From 3d6c1782c4fc2ed3e6a924c15042edb1f56fee36 Mon Sep 17 00:00:00 2001 From: John McCall Date: Tue, 4 May 2010 01:53:42 +0000 Subject: [PATCH] When inheriting a default argument expression, inherit the full expression, not just the inner expression. This is important if the expression has any temporaries. Fixes PR 7028. Basically a symptom of really tragic method names. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102998 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGClass.cpp | 4 ++- lib/Sema/SemaDeclCXX.cpp | 6 ++-- test/CodeGenCXX/default-arg-temps.cpp | 50 ++++++++++++++++++++++++--- 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 6e7208bdcb..a604eef49a 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -584,7 +584,9 @@ static void EmitMemberInitializer(CodeGenFunction &CGF, LHS.isVolatileQualified()); } else { CGF.EmitAggExpr(MemberInit->getInit(), LHS.getAddress(), - LHS.isVolatileQualified(), false, true); + LHS.isVolatileQualified(), + /*IgnoreResult*/ false, + /*IsInitializer*/ true); if (!CGF.Exceptions) return; diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index c4467850c9..6259b85af4 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -298,13 +298,15 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) { << OldParam->getDefaultArgRange(); Invalid = true; } else if (OldParam->hasDefaultArg()) { - // Merge the old default argument into the new parameter + // Merge the old default argument into the new parameter. + // It's important to use getInit() here; getDefaultArg() + // strips off any top-level CXXExprWithTemporaries. NewParam->setHasInheritedDefaultArg(); if (OldParam->hasUninstantiatedDefaultArg()) NewParam->setUninstantiatedDefaultArg( OldParam->getUninstantiatedDefaultArg()); else - NewParam->setDefaultArg(OldParam->getDefaultArg()); + NewParam->setDefaultArg(OldParam->getInit()); } else if (NewParam->hasDefaultArg()) { if (New->getDescribedFunctionTemplate()) { // Paragraph 4, quoted above, only applies to non-template functions. diff --git a/test/CodeGenCXX/default-arg-temps.cpp b/test/CodeGenCXX/default-arg-temps.cpp index e523eb0cfd..e4a06770cd 100644 --- a/test/CodeGenCXX/default-arg-temps.cpp +++ b/test/CodeGenCXX/default-arg-temps.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm %s -o %t -triple=x86_64-apple-darwin9 +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s struct T { T(); @@ -13,20 +13,62 @@ public: X(const X&, const T& t = T()); }; +// CHECK: define void @_Z1gv() void g() { - // RUN: grep "call void @_ZN1TC1Ev" %t | count 4 - // RUN: grep "call void @_ZN1TD1Ev" %t | count 4 + // CHECK: call void @_ZN1TC1Ev([[T:%.*]]* [[AGG1:%.*]]) + // CHECK-NEXT: call void @_Z1fRK1T([[T]]* [[AGG1]]) + // CHECK-NEXT: call void @_ZN1TD1Ev([[T]]* [[AGG1]]) f(); + + // CHECK-NEXT: call void @_ZN1TC1Ev([[T:%.*]]* [[AGG2:%.*]]) + // CHECK-NEXT: call void @_Z1fRK1T([[T]]* [[AGG2]]) + // CHECK-NEXT: call void @_ZN1TD1Ev([[T]]* [[AGG2]]) f(); + // CHECK-NEXT: call void @_ZN1XC1Ev( X a; + + // CHECK-NEXT: call void @_ZN1TC1Ev( + // CHECK-NEXT: call void @_ZN1XC1ERKS_RK1T( + // CHECK-NEXT: call void @_ZN1TD1Ev( X b(a); + + // CHECK-NEXT: call void @_ZN1TC1Ev( + // CHECK-NEXT: call void @_ZN1XC1ERKS_RK1T( + // CHECK-NEXT: call void @_ZN1TD1Ev( X c = a; } -// RUN: grep memset %t class obj{ int a; float b; double d; }; +// CHECK: define void @_Z1hv() void h() { + // CHECK: call void @llvm.memset.p0i8.i64( + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64( obj o = obj(); } + +// PR7028 - mostly this shouldn't crash +namespace test1 { + struct A { A(); }; + struct B { B(); ~B(); }; + + struct C { + C(const B &file = B()); + }; + C::C(const B &file) {} + + struct D { + C c; + A a; + + // CHECK: define linkonce_odr void @_ZN5test11DC2Ev( + // CHECK: call void @_ZN5test11BC1Ev( + // CHECK-NEXT: call void @_ZN5test11CC1ERKNS_1BE( + // CHECK-NEXT: call void @_ZN5test11BD1Ev( + // CHECK: call void @_ZN5test11AC1Ev( + D() : c(), a() {} + }; + + D d; +} -- 2.40.0