Index: docs/ClangCommandLineReference.rst =================================================================== --- docs/ClangCommandLineReference.rst +++ docs/ClangCommandLineReference.rst @@ -1543,6 +1543,10 @@ Disable implicit builtin knowledge of a specific function +.. option:: -fdelete-null-pointer-checks, -fno-delete-null-pointer-checks + +Assume that null pointers cannot be dereferenced safely and any code/data cannot reside at address zero. + .. option:: -fno-elide-type Do not elide types when printing diagnostics Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1076,6 +1076,12 @@ Flags<[CC1Option]>; def fno_rewrite_imports : Flag<["-"], "fno-rewrite-imports">, Group; +def fdelete_null_pointer_checks : Flag<["-"], + "fdelete-null-pointer-checks">, Group; +def fno_delete_null_pointer_checks : Flag<["-"], + "fno-delete-null-pointer-checks">, Group, Flags<[CC1Option]>, + HelpText<"Assume that null pointer dereferences are not undefined">; + def frewrite_map_file : Separate<["-"], "frewrite-map-file">, Group, Flags<[ DriverOption, CC1Option ]>; @@ -2843,8 +2849,6 @@ defm eliminate_unused_debug_types : BooleanFFlag<"eliminate-unused-debug-types">, Group; defm branch_count_reg : BooleanFFlag<"branch-count-reg">, Group; defm default_inline : BooleanFFlag<"default-inline">, Group; -defm delete_null_pointer_checks : BooleanFFlag<"delete-null-pointer-checks">, - Group; defm fat_lto_objects : BooleanFFlag<"fat-lto-objects">, Group; defm float_store : BooleanFFlag<"float-store">, Group; defm friend_injection : BooleanFFlag<"friend-injection">, Group; Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def +++ include/clang/Frontend/CodeGenOptions.def @@ -130,6 +130,7 @@ CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled. CODEGENOPT(NoInfsFPMath , 1, 0) ///< Assume FP arguments, results not +-Inf. CODEGENOPT(NoSignedZeros , 1, 0) ///< Allow ignoring the signedness of FP zero +CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined. CODEGENOPT(Reassociate , 1, 0) ///< Allow reassociation of FP math ops CODEGENOPT(ReciprocalMath , 1, 0) ///< Allow FP divisions to be reassociated. CODEGENOPT(NoTrappingMath , 1, 0) ///< Set when -fno-trapping-math is enabled. Index: lib/CodeGen/CGCall.cpp =================================================================== --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -1734,6 +1734,8 @@ FuncAttrs.addAttribute("less-precise-fpmad", llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD)); + if (CodeGenOpts.NullPointerIsValid) + FuncAttrs.addAttribute("null-pointer-is-valid", "true"); if (!CodeGenOpts.FPDenormalMode.empty()) FuncAttrs.addAttribute("denormal-fp-math", CodeGenOpts.FPDenormalMode); @@ -1867,7 +1869,8 @@ } if (TargetDecl->hasAttr()) RetAttrs.addAttribute(llvm::Attribute::NoAlias); - if (TargetDecl->hasAttr()) + if (TargetDecl->hasAttr() && + !CodeGenOpts.NullPointerIsValid) RetAttrs.addAttribute(llvm::Attribute::NonNull); if (TargetDecl->hasAttr()) FuncAttrs.addAttribute("no_caller_saved_registers"); @@ -1974,7 +1977,8 @@ if (!PTy->isIncompleteType() && PTy->isConstantSizeType()) RetAttrs.addDereferenceableAttr(getContext().getTypeSizeInChars(PTy) .getQuantity()); - else if (getContext().getTargetAddressSpace(PTy) == 0) + else if (getContext().getTargetAddressSpace(PTy) == 0 && + !CodeGenOpts.NullPointerIsValid) RetAttrs.addAttribute(llvm::Attribute::NonNull); } @@ -2083,7 +2087,8 @@ if (!PTy->isIncompleteType() && PTy->isConstantSizeType()) Attrs.addDereferenceableAttr(getContext().getTypeSizeInChars(PTy) .getQuantity()); - else if (getContext().getTargetAddressSpace(PTy) == 0) + else if (getContext().getTargetAddressSpace(PTy) == 0 && + !CodeGenOpts.NullPointerIsValid) Attrs.addAttribute(llvm::Attribute::NonNull); } @@ -2343,7 +2348,8 @@ if (const ParmVarDecl *PVD = dyn_cast(Arg)) { if (getNonNullAttr(CurCodeDecl, PVD, PVD->getType(), - PVD->getFunctionScopeIndex())) + PVD->getFunctionScopeIndex()) && + !CGM.getCodeGenOpts().NullPointerIsValid) AI->addAttr(llvm::Attribute::NonNull); QualType OTy = PVD->getOriginalType(); @@ -2362,7 +2368,8 @@ Attrs.addDereferenceableAttr( getContext().getTypeSizeInChars(ETy).getQuantity()*ArrSize); AI->addAttrs(Attrs); - } else if (getContext().getTargetAddressSpace(ETy) == 0) { + } else if (getContext().getTargetAddressSpace(ETy) == 0 && + !CGM.getCodeGenOpts().NullPointerIsValid) { AI->addAttr(llvm::Attribute::NonNull); } } @@ -2372,7 +2379,8 @@ // we can't use the dereferenceable attribute, but in addrspace(0) // we know that it must be nonnull. if (ArrTy->getSizeModifier() == VariableArrayType::Static && - !getContext().getTargetAddressSpace(ArrTy->getElementType())) + !getContext().getTargetAddressSpace(ArrTy->getElementType()) && + !CGM.getCodeGenOpts().NullPointerIsValid) AI->addAttr(llvm::Attribute::NonNull); } Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -3344,6 +3344,10 @@ options::OPT_fno_merge_all_constants, false)) CmdArgs.push_back("-fmerge-all-constants"); + if (Args.hasFlag(options::OPT_fno_delete_null_pointer_checks, + options::OPT_fdelete_null_pointer_checks, false)) + CmdArgs.push_back("-fno-delete-null-pointer-checks"); + // LLVM Code Generator Options. if (Args.hasArg(options::OPT_frewrite_map_file) || Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -746,6 +746,8 @@ Opts.NoUseJumpTables = Args.hasArg(OPT_fno_jump_tables); + Opts.NullPointerIsValid = Args.hasArg(OPT_fno_delete_null_pointer_checks); + Opts.ProfileSampleAccurate = Args.hasArg(OPT_fprofile_sample_accurate); Opts.PrepareForLTO = Args.hasArg(OPT_flto, OPT_flto_EQ); Index: test/CodeGen/delete-null-pointer-checks.c =================================================================== --- /dev/null +++ test/CodeGen/delete-null-pointer-checks.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck -check-prefix=NULL-POINTER-INVALID %s +// RUN: %clang_cc1 -emit-llvm -o - %s -fno-delete-null-pointer-checks | FileCheck -check-prefix=NULL-POINTER-VALID %s + +int test1(int a) { + return a; +} + +// NULL-POINTER-INVALID-NOT: attributes #0 = {{.*}} "null-pointer-is-valid"="true" +// NULL-POINTER-VALID: attributes #0 = {{.*}} "null-pointer-is-valid"="true" Index: test/CodeGen/nonnull.c =================================================================== --- test/CodeGen/nonnull.c +++ test/CodeGen/nonnull.c @@ -1,32 +1,39 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm < %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm < %s | FileCheck -check-prefix=PREFIX-NONNULL %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -fno-delete-null-pointer-checks < %s | FileCheck -check-prefix=PREFIX-NO-NULL %s -// CHECK: define void @foo(i32* nonnull %x) +// PREFIX-NONNULL: define void @foo(i32* nonnull %x) +// PREFIX-NO-NULL: define void @foo(i32* %x) void foo(int * __attribute__((nonnull)) x) { *x = 0; } -// CHECK: define void @bar(i32* nonnull %x) +// PREFIX-NONNULL: define void @bar(i32* nonnull %x) +// PREFIX-NO-NULL: define void @bar(i32* %x) void bar(int * x) __attribute__((nonnull(1))) { *x = 0; } -// CHECK: define void @bar2(i32* %x, i32* nonnull %y) +// PREFIX-NONNULL: define void @bar2(i32* %x, i32* nonnull %y) +// PREFIX-NO-NULL: define void @bar2(i32* %x, i32* %y) void bar2(int * x, int * y) __attribute__((nonnull(2))) { *x = 0; } static int a; -// CHECK: define nonnull i32* @bar3() +// PREFIX-NONNULL: define nonnull i32* @bar3() +// PREFIX-NO-NULL: define i32* @bar3() int * bar3() __attribute__((returns_nonnull)) { return &a; } -// CHECK: define i32 @bar4(i32 %n, i32* nonnull %p) +// PREFIX-NONNULL: define i32 @bar4(i32 %n, i32* nonnull %p) +// PREFIX-NO-NULL: define i32 @bar4(i32 %n, i32* %p) int bar4(int n, int *p) __attribute__((nonnull)) { return n + *p; } -// CHECK: define i32 @bar5(i32 %n, i32* nonnull %p) +// PREFIX-NONNULL: define i32 @bar5(i32 %n, i32* nonnull %p) +// PREFIX-NO-NULL: define i32 @bar5(i32 %n, i32* %p) int bar5(int n, int *p) __attribute__((nonnull(1, 2))) { return n + *p; } @@ -37,15 +44,18 @@ double d; } TransparentUnion __attribute__((transparent_union)); -// CHECK: define i32 @bar6(i64 % +// PREFIX-NONNULL: define i32 @bar6(i64 % +// PREFIX-NO-NULL: define i32 @bar6(i64 % int bar6(TransparentUnion tu) __attribute__((nonnull(1))) { return *tu.p; } -// CHECK: define void @bar7(i32* nonnull %a, i32* nonnull %b) +// PREFIX-NONNULL: define void @bar7(i32* nonnull %a, i32* nonnull %b) +// PREFIX-NO-NULL: define void @bar7(i32* %a, i32* %b) void bar7(int *a, int *b) __attribute__((nonnull(1))) __attribute__((nonnull(2))) {} -// CHECK: define void @bar8(i32* nonnull %a, i32* nonnull %b) +// PREFIX-NONNULL: define void @bar8(i32* nonnull %a, i32* nonnull %b) +// PREFIX-NO-NULL: define void @bar8(i32* %a, i32* %b) void bar8(int *a, int *b) __attribute__((nonnull)) __attribute__((nonnull(1))) {} Index: test/CodeGen/vla.c =================================================================== --- test/CodeGen/vla.c +++ test/CodeGen/vla.c @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s -check-prefixes=PREFIX-VLA,PREFIX-NONNULL +// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -fno-delete-null-pointer-checks -o - | FileCheck %s -check-prefixes=PREFIX-VLA,PREFIX-NO-NULL int b(char* x); @@ -37,18 +38,18 @@ } // rdar://8403108 -// CHECK-LABEL: define void @f_8403108 +// PREFIX-VLA-LABEL: define void @f_8403108 void f_8403108(unsigned x) { - // CHECK: call i8* @llvm.stacksave() + // PREFIX-VLA: call i8* @llvm.stacksave() char s1[x]; while (1) { - // CHECK: call i8* @llvm.stacksave() + // PREFIX-VLA: call i8* @llvm.stacksave() char s2[x]; if (1) break; - // CHECK: call void @llvm.stackrestore(i8* + // PREFIX-VLA: call void @llvm.stackrestore(i8* } - // CHECK: call void @llvm.stackrestore(i8* + // PREFIX-VLA: call void @llvm.stackrestore(i8* } // pr7827 @@ -56,20 +57,20 @@ void test() { int bork[4][13]; - // CHECK: call void @function(i16 signext 1, i32* null) + // PREFIX-VLA: call void @function(i16 signext 1, i32* null) function(1, 0); - // CHECK: call void @function(i16 signext 1, i32* inttoptr + // PREFIX-VLA: call void @function(i16 signext 1, i32* inttoptr function(1, 0xbadbeef); // expected-warning {{incompatible integer to pointer conversion passing}} - // CHECK: call void @function(i16 signext 1, i32* {{.*}}) + // PREFIX-VLA: call void @function(i16 signext 1, i32* {{.*}}) function(1, bork); } void function1(short width, int data[][width][width]) {} void test1() { int bork[4][13][15]; - // CHECK: call void @function1(i16 signext 1, i32* {{.*}}) + // PREFIX-VLA: call void @function1(i16 signext 1, i32* {{.*}}) function1(1, bork); - // CHECK: call void @function(i16 signext 1, i32* {{.*}}) + // PREFIX-VLA: call void @function(i16 signext 1, i32* {{.*}}) function(1, bork[2]); } @@ -79,128 +80,129 @@ { GLOB = 0; char b[1][n+3]; /* Variable length array. */ - // CHECK: [[tmp_1:%.*]] = load i32, i32* @GLOB, align 4 - // CHECK-NEXT: add nsw i32 [[tmp_1]], 1 + // PREFIX-VLA: [[tmp_1:%.*]] = load i32, i32* @GLOB, align 4 + // PREFIX-VLA-NEXT: add nsw i32 [[tmp_1]], 1 __typeof__(b[GLOB++]) c; return GLOB; } // http://llvm.org/PR8567 -// CHECK-LABEL: define double @test_PR8567 +// PREFIX-VLA-LABEL: define double @test_PR8567 double test_PR8567(int n, double (*p)[n][5]) { - // CHECK: [[NV:%.*]] = alloca i32, align 4 - // CHECK-NEXT: [[PV:%.*]] = alloca [5 x double]*, align 4 - // CHECK-NEXT: store - // CHECK-NEXT: store - // CHECK-NEXT: [[N:%.*]] = load i32, i32* [[NV]], align 4 - // CHECK-NEXT: [[P:%.*]] = load [5 x double]*, [5 x double]** [[PV]], align 4 - // CHECK-NEXT: [[T0:%.*]] = mul nsw i32 1, [[N]] - // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [5 x double], [5 x double]* [[P]], i32 [[T0]] - // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [5 x double], [5 x double]* [[T1]], i32 2 - // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [5 x double], [5 x double]* [[T2]], i32 0, i32 3 - // CHECK-NEXT: [[T4:%.*]] = load double, double* [[T3]] - // CHECK-NEXT: ret double [[T4]] + // PREFIX-VLA: [[NV:%.*]] = alloca i32, align 4 + // PREFIX-VLA-NEXT: [[PV:%.*]] = alloca [5 x double]*, align 4 + // PREFIX-VLA-NEXT: store + // PREFIX-VLA-NEXT: store + // PREFIX-VLA-NEXT: [[N:%.*]] = load i32, i32* [[NV]], align 4 + // PREFIX-VLA-NEXT: [[P:%.*]] = load [5 x double]*, [5 x double]** [[PV]], align 4 + // PREFIX-VLA-NEXT: [[T0:%.*]] = mul nsw i32 1, [[N]] + // PREFIX-VLA-NEXT: [[T1:%.*]] = getelementptr inbounds [5 x double], [5 x double]* [[P]], i32 [[T0]] + // PREFIX-VLA-NEXT: [[T2:%.*]] = getelementptr inbounds [5 x double], [5 x double]* [[T1]], i32 2 + // PREFIX-VLA-NEXT: [[T3:%.*]] = getelementptr inbounds [5 x double], [5 x double]* [[T2]], i32 0, i32 3 + // PREFIX-VLA-NEXT: [[T4:%.*]] = load double, double* [[T3]] + // PREFIX-VLA-NEXT: ret double [[T4]] return p[1][2][3]; } int test4(unsigned n, char (*p)[n][n+1][6]) { - // CHECK-LABEL: define i32 @test4( - // CHECK: [[N:%.*]] = alloca i32, align 4 - // CHECK-NEXT: [[P:%.*]] = alloca [6 x i8]*, align 4 - // CHECK-NEXT: [[P2:%.*]] = alloca [6 x i8]*, align 4 - // CHECK-NEXT: store i32 - // CHECK-NEXT: store [6 x i8]* + // PREFIX-VLA-LABEL: define i32 @test4( + // PREFIX-VLA: [[N:%.*]] = alloca i32, align 4 + // PREFIX-VLA-NEXT: [[P:%.*]] = alloca [6 x i8]*, align 4 + // PREFIX-VLA-NEXT: [[P2:%.*]] = alloca [6 x i8]*, align 4 + // PREFIX-VLA-NEXT: store i32 + // PREFIX-VLA-NEXT: store [6 x i8]* // VLA captures. - // CHECK-NEXT: [[DIM0:%.*]] = load i32, i32* [[N]], align 4 - // CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[N]], align 4 - // CHECK-NEXT: [[DIM1:%.*]] = add i32 [[T0]], 1 - - // CHECK-NEXT: [[T0:%.*]] = load [6 x i8]*, [6 x i8]** [[P]], align 4 - // CHECK-NEXT: [[T1:%.*]] = load i32, i32* [[N]], align 4 - // CHECK-NEXT: [[T2:%.*]] = udiv i32 [[T1]], 2 - // CHECK-NEXT: [[T3:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]] - // CHECK-NEXT: [[T4:%.*]] = mul nsw i32 [[T2]], [[T3]] - // CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [6 x i8], [6 x i8]* [[T0]], i32 [[T4]] - // CHECK-NEXT: [[T6:%.*]] = load i32, i32* [[N]], align 4 - // CHECK-NEXT: [[T7:%.*]] = udiv i32 [[T6]], 4 - // CHECK-NEXT: [[T8:%.*]] = sub i32 0, [[T7]] - // CHECK-NEXT: [[T9:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]] - // CHECK-NEXT: [[T10:%.*]] = mul nsw i32 [[T8]], [[T9]] - // CHECK-NEXT: [[T11:%.*]] = getelementptr inbounds [6 x i8], [6 x i8]* [[T5]], i32 [[T10]] - // CHECK-NEXT: store [6 x i8]* [[T11]], [6 x i8]** [[P2]], align 4 + // PREFIX-VLA-NEXT: [[DIM0:%.*]] = load i32, i32* [[N]], align 4 + // PREFIX-VLA-NEXT: [[T0:%.*]] = load i32, i32* [[N]], align 4 + // PREFIX-VLA-NEXT: [[DIM1:%.*]] = add i32 [[T0]], 1 + + // PREFIX-VLA-NEXT: [[T0:%.*]] = load [6 x i8]*, [6 x i8]** [[P]], align 4 + // PREFIX-VLA-NEXT: [[T1:%.*]] = load i32, i32* [[N]], align 4 + // PREFIX-VLA-NEXT: [[T2:%.*]] = udiv i32 [[T1]], 2 + // PREFIX-VLA-NEXT: [[T3:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]] + // PREFIX-VLA-NEXT: [[T4:%.*]] = mul nsw i32 [[T2]], [[T3]] + // PREFIX-VLA-NEXT: [[T5:%.*]] = getelementptr inbounds [6 x i8], [6 x i8]* [[T0]], i32 [[T4]] + // PREFIX-VLA-NEXT: [[T6:%.*]] = load i32, i32* [[N]], align 4 + // PREFIX-VLA-NEXT: [[T7:%.*]] = udiv i32 [[T6]], 4 + // PREFIX-VLA-NEXT: [[T8:%.*]] = sub i32 0, [[T7]] + // PREFIX-VLA-NEXT: [[T9:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]] + // PREFIX-VLA-NEXT: [[T10:%.*]] = mul nsw i32 [[T8]], [[T9]] + // PREFIX-VLA-NEXT: [[T11:%.*]] = getelementptr inbounds [6 x i8], [6 x i8]* [[T5]], i32 [[T10]] + // PREFIX-VLA-NEXT: store [6 x i8]* [[T11]], [6 x i8]** [[P2]], align 4 __typeof(p) p2 = (p + n/2) - n/4; - // CHECK-NEXT: [[T0:%.*]] = load [6 x i8]*, [6 x i8]** [[P2]], align 4 - // CHECK-NEXT: [[T1:%.*]] = load [6 x i8]*, [6 x i8]** [[P]], align 4 - // CHECK-NEXT: [[T2:%.*]] = ptrtoint [6 x i8]* [[T0]] to i32 - // CHECK-NEXT: [[T3:%.*]] = ptrtoint [6 x i8]* [[T1]] to i32 - // CHECK-NEXT: [[T4:%.*]] = sub i32 [[T2]], [[T3]] - // CHECK-NEXT: [[T5:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]] - // CHECK-NEXT: [[T6:%.*]] = mul nuw i32 6, [[T5]] - // CHECK-NEXT: [[T7:%.*]] = sdiv exact i32 [[T4]], [[T6]] - // CHECK-NEXT: ret i32 [[T7]] + // PREFIX-VLA-NEXT: [[T0:%.*]] = load [6 x i8]*, [6 x i8]** [[P2]], align 4 + // PREFIX-VLA-NEXT: [[T1:%.*]] = load [6 x i8]*, [6 x i8]** [[P]], align 4 + // PREFIX-VLA-NEXT: [[T2:%.*]] = ptrtoint [6 x i8]* [[T0]] to i32 + // PREFIX-VLA-NEXT: [[T3:%.*]] = ptrtoint [6 x i8]* [[T1]] to i32 + // PREFIX-VLA-NEXT: [[T4:%.*]] = sub i32 [[T2]], [[T3]] + // PREFIX-VLA-NEXT: [[T5:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]] + // PREFIX-VLA-NEXT: [[T6:%.*]] = mul nuw i32 6, [[T5]] + // PREFIX-VLA-NEXT: [[T7:%.*]] = sdiv exact i32 [[T4]], [[T6]] + // PREFIX-VLA-NEXT: ret i32 [[T7]] return p2 - p; } // rdar://11485774 void test5(void) { - // CHECK-LABEL: define void @test5( + // PREFIX-VLA-LABEL: define void @test5( int a[5], i = 0; - // CHECK: [[A:%.*]] = alloca [5 x i32], align 4 - // CHECK-NEXT: [[I:%.*]] = alloca i32, align 4 - // CHECK-NEXT: [[CL:%.*]] = alloca i32*, align 4 - // CHECK-NEXT: store i32 0, i32* [[I]], align 4 + // PREFIX-VLA: [[A:%.*]] = alloca [5 x i32], align 4 + // PREFIX-VLA-NEXT: [[I:%.*]] = alloca i32, align 4 + // PREFIX-VLA-NEXT: [[CL:%.*]] = alloca i32*, align 4 + // PREFIX-VLA-NEXT: store i32 0, i32* [[I]], align 4 (typeof(++i, (int (*)[i])a)){&a} += 0; - // CHECK-NEXT: [[Z:%.*]] = load i32, i32* [[I]], align 4 - // CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[Z]], 1 - // CHECK-NEXT: store i32 [[INC]], i32* [[I]], align 4 - // CHECK-NEXT: [[O:%.*]] = load i32, i32* [[I]], align 4 - // CHECK-NEXT: [[AR:%.*]] = getelementptr inbounds [5 x i32], [5 x i32]* [[A]], i32 0, i32 0 - // CHECK-NEXT: [[T:%.*]] = bitcast [5 x i32]* [[A]] to i32* - // CHECK-NEXT: store i32* [[T]], i32** [[CL]] - // CHECK-NEXT: [[TH:%.*]] = load i32*, i32** [[CL]] - // CHECK-NEXT: [[VLAIX:%.*]] = mul nsw i32 0, [[O]] - // CHECK-NEXT: [[ADDPTR:%.*]] = getelementptr inbounds i32, i32* [[TH]], i32 [[VLAIX]] - // CHECK-NEXT: store i32* [[ADDPTR]], i32** [[CL]] + // PREFIX-VLA-NEXT: [[Z:%.*]] = load i32, i32* [[I]], align 4 + // PREFIX-VLA-NEXT: [[INC:%.*]] = add nsw i32 [[Z]], 1 + // PREFIX-VLA-NEXT: store i32 [[INC]], i32* [[I]], align 4 + // PREFIX-VLA-NEXT: [[O:%.*]] = load i32, i32* [[I]], align 4 + // PREFIX-VLA-NEXT: [[AR:%.*]] = getelementptr inbounds [5 x i32], [5 x i32]* [[A]], i32 0, i32 0 + // PREFIX-VLA-NEXT: [[T:%.*]] = bitcast [5 x i32]* [[A]] to i32* + // PREFIX-VLA-NEXT: store i32* [[T]], i32** [[CL]] + // PREFIX-VLA-NEXT: [[TH:%.*]] = load i32*, i32** [[CL]] + // PREFIX-VLA-NEXT: [[VLAIX:%.*]] = mul nsw i32 0, [[O]] + // PREFIX-VLA-NEXT: [[ADDPTR:%.*]] = getelementptr inbounds i32, i32* [[TH]], i32 [[VLAIX]] + // PREFIX-VLA-NEXT: store i32* [[ADDPTR]], i32** [[CL]] } void test6(void) { - // CHECK-LABEL: define void @test6( + // PREFIX-VLA-LABEL: define void @test6( int n = 20, **a, i=0; - // CHECK: [[N:%.*]] = alloca i32, align 4 - // CHECK-NEXT: [[A:%.*]] = alloca i32**, align 4 - // CHECK-NEXT: [[I:%.*]] = alloca i32, align 4 + // PREFIX-VLA: [[N:%.*]] = alloca i32, align 4 + // PREFIX-VLA-NEXT: [[A:%.*]] = alloca i32**, align 4 + // PREFIX-VLA-NEXT: [[I:%.*]] = alloca i32, align 4 (int (**)[i]){&a}[0][1][5] = 0; - // CHECK-NEXT: [[CL:%.*]] = alloca i32**, align 4 - // CHECK-NEXT: store i32 20, i32* [[N]], align 4 - // CHECK-NEXT: store i32 0, i32* [[I]], align 4 - // CHECK-NEXT: [[Z:%.*]] = load i32, i32* [[I]], align 4 - // CHECK-NEXT: [[O:%.*]] = bitcast i32*** [[A]] to i32** - // CHECK-NEXT: store i32** [[O]], i32*** [[CL]] - // CHECK-NEXT: [[T:%.*]] = load i32**, i32*** [[CL]] - // CHECK-NEXT: [[IX:%.*]] = getelementptr inbounds i32*, i32** [[T]], i32 0 - // CHECK-NEXT: [[TH:%.*]] = load i32*, i32** [[IX]], align 4 - // CHECK-NEXT: [[F:%.*]] = mul nsw i32 1, [[Z]] - // CHECK-NEXT: [[IX1:%.*]] = getelementptr inbounds i32, i32* [[TH]], i32 [[F]] - // CHECK-NEXT: [[IX2:%.*]] = getelementptr inbounds i32, i32* [[IX1]], i32 5 - // CHECK-NEXT: store i32 0, i32* [[IX2]], align 4 + // PREFIX-VLA-NEXT: [[CL:%.*]] = alloca i32**, align 4 + // PREFIX-VLA-NEXT: store i32 20, i32* [[N]], align 4 + // PREFIX-VLA-NEXT: store i32 0, i32* [[I]], align 4 + // PREFIX-VLA-NEXT: [[Z:%.*]] = load i32, i32* [[I]], align 4 + // PREFIX-VLA-NEXT: [[O:%.*]] = bitcast i32*** [[A]] to i32** + // PREFIX-VLA-NEXT: store i32** [[O]], i32*** [[CL]] + // PREFIX-VLA-NEXT: [[T:%.*]] = load i32**, i32*** [[CL]] + // PREFIX-VLA-NEXT: [[IX:%.*]] = getelementptr inbounds i32*, i32** [[T]], i32 0 + // PREFIX-VLA-NEXT: [[TH:%.*]] = load i32*, i32** [[IX]], align 4 + // PREFIX-VLA-NEXT: [[F:%.*]] = mul nsw i32 1, [[Z]] + // PREFIX-VLA-NEXT: [[IX1:%.*]] = getelementptr inbounds i32, i32* [[TH]], i32 [[F]] + // PREFIX-VLA-NEXT: [[IX2:%.*]] = getelementptr inbounds i32, i32* [[IX1]], i32 5 + // PREFIX-VLA-NEXT: store i32 0, i32* [[IX2]], align 4 } // Follow gcc's behavior for VLAs in parameter lists. PR9559. void test7(int a[b(0)]) { - // CHECK-LABEL: define void @test7( - // CHECK: call i32 @b(i8* null) + // PREFIX-VLA-LABEL: define void @test7( + // PREFIX-VLA: call i32 @b(i8* null) } // Make sure we emit dereferenceable or nonnull when the static keyword is // provided. void test8(int a[static 3]) { } -// CHECK: define void @test8(i32* dereferenceable(12) %a) +// PREFIX-VLA: define void @test8(i32* dereferenceable(12) %a) void test9(int n, int a[static n]) { } -// CHECK: define void @test9(i32 %n, i32* nonnull %a) +// PREFIX-NONNULL: define void @test9(i32 %n, i32* nonnull %a) +// PREFIX-NO-NULL: define void @test9(i32 %n, i32* %a) Index: test/CodeGenCXX/address-space-ref.cpp =================================================================== --- test/CodeGenCXX/address-space-ref.cpp +++ test/CodeGenCXX/address-space-ref.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s -check-prefixes=PREFIX-COMMON,PREFIX-NONNULL +// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -fno-delete-null-pointer-checks -emit-llvm -o - | FileCheck %s -check-prefixes=PREFIX-COMMON,PREFIX-NO-NULL // For a reference to a complete type, output the dereferenceable attribute (in // any address space). @@ -9,7 +10,7 @@ return x; } -// CHECK: define dereferenceable(4) i32 addrspace(1)* @_Z3fooRU3AS1iS0_(i32 addrspace(1)* dereferenceable(4) %x, i32 addrspace(1)* dereferenceable(4) %y) +// PREFIX-COMMON: define dereferenceable(4) i32 addrspace(1)* @_Z3fooRU3AS1iS0_(i32 addrspace(1)* dereferenceable(4) %x, i32 addrspace(1)* dereferenceable(4) %y) // For a reference to an incomplete type in an alternate address space, output // neither dereferenceable nor nonnull. @@ -21,7 +22,7 @@ return x; } -// CHECK: define %class.bc addrspace(1)* @_Z3barRU3AS12bcS1_(%class.bc addrspace(1)* %x, %class.bc addrspace(1)* %y) +// PREFIX-COMMON: define %class.bc addrspace(1)* @_Z3barRU3AS12bcS1_(%class.bc addrspace(1)* %x, %class.bc addrspace(1)* %y) // For a reference to an incomplete type in addrspace(0), output nonnull. @@ -29,6 +30,7 @@ return x; } -// CHECK: define nonnull %class.bc* @_Z4bar2R2bcS0_(%class.bc* nonnull %x, %class.bc* nonnull %y) +// PREFIX-NON-NULL: define nonnull %class.bc* @_Z4bar2R2bcS0_(%class.bc* nonnull %x, %class.bc* nonnull %y) +// PREFIX-NO-NULL: define %class.bc* @_Z4bar2R2bcS0_(%class.bc* %x, %class.bc* %y) Index: test/CodeGenCXX/constructors.cpp =================================================================== --- test/CodeGenCXX/constructors.cpp +++ test/CodeGenCXX/constructors.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s --implicit-check-not=should_not_appear_in_output +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s --implicit-check-not=should_not_appear_in_output --check-prefixes=CHECK-COMMON,CHECK-NONNULL +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -fno-delete-null-pointer-checks -o - | FileCheck %s --implicit-check-not=should_not_appear_in_output --check-prefixes=CHECK-COMMON,CHECK-NO-NULL struct Member { int x; Member(); Member(int); Member(const Member &); }; struct VBase { int x; VBase(); VBase(int); VBase(const VBase &); }; @@ -21,19 +22,21 @@ A::A(struct Undeclared &ref) : mem(0) {} // Check that delegation works. -// CHECK-LABEL: define void @_ZN1AC2ER10Undeclared(%struct.A* %this, %struct.Undeclared* nonnull %ref) unnamed_addr -// CHECK: call void @_ZN6MemberC1Ei( +// CHECK-NONNULL-LABEL: define void @_ZN1AC2ER10Undeclared(%struct.A* %this, %struct.Undeclared* nonnull %ref) unnamed_addr +// CHECK-NO-NULL-LABEL: define void @_ZN1AC2ER10Undeclared(%struct.A* %this, %struct.Undeclared* %ref) unnamed_addr +// CHECK-COMMON: call void @_ZN6MemberC1Ei( -// CHECK-LABEL: define void @_ZN1AC1ER10Undeclared(%struct.A* %this, %struct.Undeclared* nonnull %ref) unnamed_addr -// CHECK: call void @_ZN1AC2ER10Undeclared( +// CHECK-NONNULL-LABEL: define void @_ZN1AC1ER10Undeclared(%struct.A* %this, %struct.Undeclared* nonnull %ref) unnamed_addr +// CHECK-NO-NULL-LABEL: define void @_ZN1AC1ER10Undeclared(%struct.A* %this, %struct.Undeclared* %ref) unnamed_addr +// CHECK-COMMON: call void @_ZN1AC2ER10Undeclared( A::A(ValueClass v) : mem(v.y - v.x) {} -// CHECK-LABEL: define void @_ZN1AC2E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr -// CHECK: call void @_ZN6MemberC1Ei( +// CHECK-COMMON-LABEL: define void @_ZN1AC2E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr +// CHECK-COMMON: call void @_ZN6MemberC1Ei( -// CHECK-LABEL: define void @_ZN1AC1E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr -// CHECK: call void @_ZN1AC2E10ValueClass( +// CHECK-COMMON-LABEL: define void @_ZN1AC1E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr +// CHECK-COMMON: call void @_ZN1AC2E10ValueClass( /* Test that things work for inheritance. */ struct B : A { @@ -43,12 +46,14 @@ B::B(struct Undeclared &ref) : A(ref), mem(1) {} -// CHECK-LABEL: define void @_ZN1BC2ER10Undeclared(%struct.B* %this, %struct.Undeclared* nonnull %ref) unnamed_addr -// CHECK: call void @_ZN1AC2ER10Undeclared( -// CHECK: call void @_ZN6MemberC1Ei( +// CHECK-NONNULL-LABEL: define void @_ZN1BC2ER10Undeclared(%struct.B* %this, %struct.Undeclared* nonnull %ref) unnamed_addr +// CHECK-NO-NULL-LABEL: define void @_ZN1BC2ER10Undeclared(%struct.B* %this, %struct.Undeclared* %ref) unnamed_addr +// CHECK-COMMON: call void @_ZN1AC2ER10Undeclared( +// CHECK-COMMON: call void @_ZN6MemberC1Ei( -// CHECK-LABEL: define void @_ZN1BC1ER10Undeclared(%struct.B* %this, %struct.Undeclared* nonnull %ref) unnamed_addr -// CHECK: call void @_ZN1BC2ER10Undeclared( +// CHECK-NONNULL-LABEL: define void @_ZN1BC1ER10Undeclared(%struct.B* %this, %struct.Undeclared* nonnull %ref) unnamed_addr +// CHECK-NO-NULL-LABEL: define void @_ZN1BC1ER10Undeclared(%struct.B* %this, %struct.Undeclared* %ref) unnamed_addr +// CHECK-COMMON: call void @_ZN1BC2ER10Undeclared( /* Test that the delegation optimization is disabled for classes with @@ -62,13 +67,13 @@ }; C::C(int x) : A(ValueClass(x, x+1)), mem(x * x) {} -// CHECK-LABEL: define void @_ZN1CC2Ei(%struct.C* %this, i8** %vtt, i32 %x) unnamed_addr -// CHECK: call void @_ZN6MemberC1Ei( +// CHECK-COMMON-LABEL: define void @_ZN1CC2Ei(%struct.C* %this, i8** %vtt, i32 %x) unnamed_addr +// CHECK-COMMON: call void @_ZN6MemberC1Ei( -// CHECK-LABEL: define void @_ZN1CC1Ei(%struct.C* %this, i32 %x) unnamed_addr -// CHECK: call void @_ZN10ValueClassC1Eii( -// CHECK: call void @_ZN1AC2E10ValueClass( -// CHECK: call void @_ZN6MemberC1Ei( +// CHECK-COMMON-LABEL: define void @_ZN1CC1Ei(%struct.C* %this, i32 %x) unnamed_addr +// CHECK-COMMON: call void @_ZN10ValueClassC1Eii( +// CHECK-COMMON: call void @_ZN1AC2E10ValueClass( +// CHECK-COMMON: call void @_ZN6MemberC1Ei( /* Test that the delegation optimization is disabled for varargs @@ -80,15 +85,15 @@ D::D(int x, ...) : A(ValueClass(x, x+1)), mem(x*x) {} -// CHECK-LABEL: define void @_ZN1DC2Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr -// CHECK: call void @_ZN10ValueClassC1Eii( -// CHECK: call void @_ZN1AC2E10ValueClass( -// CHECK: call void @_ZN6MemberC1Ei( +// CHECK-COMMON-LABEL: define void @_ZN1DC2Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr +// CHECK-COMMON: call void @_ZN10ValueClassC1Eii( +// CHECK-COMMON: call void @_ZN1AC2E10ValueClass( +// CHECK-COMMON: call void @_ZN6MemberC1Ei( -// CHECK-LABEL: define void @_ZN1DC1Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr -// CHECK: call void @_ZN10ValueClassC1Eii( -// CHECK: call void @_ZN1AC2E10ValueClass( -// CHECK: call void @_ZN6MemberC1Ei( +// CHECK-COMMON-LABEL: define void @_ZN1DC1Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr +// CHECK-COMMON: call void @_ZN10ValueClassC1Eii( +// CHECK-COMMON: call void @_ZN1AC2E10ValueClass( +// CHECK-COMMON: call void @_ZN6MemberC1Ei( // PR6622: this shouldn't crash namespace test0 { @@ -105,9 +110,9 @@ struct A { A(); void *ptr; }; struct B { B(); int x; A a[0]; }; B::B() {} - // CHECK-LABEL: define void @_ZN5test11BC2Ev( - // CHECK: [[THIS:%.*]] = load [[B:%.*]]*, [[B:%.*]]** - // CHECK-NEXT: ret void + // CHECK-COMMON-LABEL: define void @_ZN5test11BC2Ev( + // CHECK-COMMON: [[THIS:%.*]] = load [[B:%.*]]*, [[B:%.*]]** + // CHECK-COMMON-NEXT: ret void } // Ensure that we @@ -134,17 +139,17 @@ virtual ~A() = 0; }; - // CHECK-LABEL: define void @_ZN8abstract1AD2Ev( - // CHECK: call {{.*}}@_ZN8abstract1XD2Ev( - // CHECK: ret + // CHECK-COMMON-LABEL: define void @_ZN8abstract1AD2Ev( + // CHECK-COMMON: call {{.*}}@_ZN8abstract1XD2Ev( + // CHECK-COMMON: ret - // CHECK-LABEL: define void @_ZN8abstract1AD1Ev( - // CHECK: call {{.*}}@llvm.trap( - // CHECK: unreachable + // CHECK-COMMON-LABEL: define void @_ZN8abstract1AD1Ev( + // CHECK-COMMON: call {{.*}}@llvm.trap( + // CHECK-COMMON: unreachable - // CHECK-LABEL: define void @_ZN8abstract1AD0Ev( - // CHECK: call {{.*}}@llvm.trap( - // CHECK: unreachable + // CHECK-COMMON-LABEL: define void @_ZN8abstract1AD0Ev( + // CHECK-COMMON: call {{.*}}@llvm.trap( + // CHECK-COMMON: unreachable A::~A() {} struct B : virtual should_not_appear_in_output, X { @@ -152,14 +157,14 @@ ~B(); }; - // CHECK-LABEL: define void @_ZN8abstract1BD2Ev( - // CHECK: call {{.*}}@_ZN8abstract1XD2Ev( - // CHECK: ret + // CHECK-COMMON-LABEL: define void @_ZN8abstract1BD2Ev( + // CHECK-COMMON: call {{.*}}@_ZN8abstract1XD2Ev( + // CHECK-COMMON: ret - // CHECK-LABEL: define void @_ZN8abstract1BD1Ev( - // CHECK: call {{.*}}@llvm.trap( - // CHECK: unreachable + // CHECK-COMMON-LABEL: define void @_ZN8abstract1BD1Ev( + // CHECK-COMMON: call {{.*}}@llvm.trap( + // CHECK-COMMON: unreachable - // CHECK-NOT: @_ZN8abstract1BD0Ev( + // CHECK-COMMON-NOT: @_ZN8abstract1BD0Ev( B::~B() {} } Index: test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp =================================================================== --- test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp +++ test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -emit-llvm -O1 -o - -fexceptions -triple=i386-pc-win32 %s | FileCheck %s +// %clang_cc1 -emit-llvm -O1 -o - -fexceptions -triple=i386-pc-win32 %s | FileCheck %s -check-prefixes=CHECK-COMMON,CHECK-NONNULL +// RUN: %clang_cc1 -emit-llvm -O1 -o - -fexceptions -fno-delete-null-pointer-checks -triple=i386-pc-win32 %s | FileCheck %s -check-prefixes=CHECK-COMMON,CHECK-NO-NULL struct S { char a; }; struct V { virtual void f(); }; @@ -7,120 +8,122 @@ struct T {}; T* test0() { return dynamic_cast((B*)0); } -// CHECK-LABEL: define dso_local noalias %struct.T* @"?test0@@YAPAUT@@XZ"() -// CHECK: ret %struct.T* null +// CHECK-COMMON-LABEL: define dso_local noalias %struct.T* @"?test0@@YAPAUT@@XZ"() +// CHECK-COMMON: ret %struct.T* null T* test1(V* x) { return &dynamic_cast(*x); } -// CHECK-LABEL: define dso_local %struct.T* @"?test1@@YAPAUT@@PAUV@@@Z"(%struct.V* %x) -// CHECK: [[CAST:%.*]] = bitcast %struct.V* %x to i8* -// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[CAST]], i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUV@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1) -// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T* -// CHECK-NEXT: ret %struct.T* [[RET]] +// CHECK-COMMON-LABEL: define dso_local %struct.T* @"?test1@@YAPAUT@@PAUV@@@Z"(%struct.V* %x) +// CHECK-COMMON: [[CAST:%.*]] = bitcast %struct.V* %x to i8* +// CHECK-COMMON-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[CAST]], i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUV@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1) +// CHECK-COMMON-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T* +// CHECK-COMMON-NEXT: ret %struct.T* [[RET]] T* test2(A* x) { return &dynamic_cast(*x); } -// CHECK-LABEL: define dso_local %struct.T* @"?test2@@YAPAUT@@PAUA@@@Z"(%struct.A* %x) -// CHECK: [[CAST:%.*]] = bitcast %struct.A* %x to i8* -// CHECK-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A, %struct.A* %x, i32 0, i32 0 -// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4 -// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 -// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4 -// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[VBOFFS]] -// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1) -// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T* -// CHECK-NEXT: ret %struct.T* [[RET]] +// CHECK-COMMON-LABEL: define dso_local %struct.T* @"?test2@@YAPAUT@@PAUA@@@Z"(%struct.A* %x) +// CHECK-COMMON: [[CAST:%.*]] = bitcast %struct.A* %x to i8* +// CHECK-COMMON-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A, %struct.A* %x, i32 0, i32 0 +// CHECK-COMMON-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4 +// CHECK-COMMON-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 +// CHECK-COMMON-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4 +// CHECK-COMMON-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[VBOFFS]] +// CHECK-COMMON-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1) +// CHECK-COMMON-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T* +// CHECK-COMMON-NEXT: ret %struct.T* [[RET]] T* test3(B* x) { return &dynamic_cast(*x); } -// CHECK-LABEL: define dso_local %struct.T* @"?test3@@YAPAUT@@PAUB@@@Z"(%struct.B* %x) -// CHECK: [[VOIDP:%.*]] = getelementptr inbounds %struct.B, %struct.B* %x, i32 0, i32 0, i32 0 -// CHECK-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 4 -// CHECK-NEXT: [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR:%.*]] to i32** -// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4 -// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 -// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4 -// CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4 -// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[DELTA]] -// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUB@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1) -// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T* -// CHECK-NEXT: ret %struct.T* [[RET]] +// CHECK-COMMON-LABEL: define dso_local %struct.T* @"?test3@@YAPAUT@@PAUB@@@Z"(%struct.B* %x) +// CHECK-COMMON: [[VOIDP:%.*]] = getelementptr inbounds %struct.B, %struct.B* %x, i32 0, i32 0, i32 0 +// CHECK-COMMON-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 4 +// CHECK-COMMON-NEXT: [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR:%.*]] to i32** +// CHECK-COMMON-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4 +// CHECK-COMMON-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 +// CHECK-COMMON-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4 +// CHECK-COMMON-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4 +// CHECK-COMMON-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[DELTA]] +// CHECK-COMMON-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUB@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1) +// CHECK-COMMON-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T* +// CHECK-COMMON-NEXT: ret %struct.T* [[RET]] T* test4(V* x) { return dynamic_cast(x); } -// CHECK-LABEL: define dso_local %struct.T* @"?test4@@YAPAUT@@PAUV@@@Z"(%struct.V* %x) -// CHECK: [[CAST:%.*]] = bitcast %struct.V* %x to i8* -// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[CAST]], i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUV@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0) -// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T* -// CHECK-NEXT: ret %struct.T* [[RET]] +// CHECK-COMMON-LABEL: define dso_local %struct.T* @"?test4@@YAPAUT@@PAUV@@@Z"(%struct.V* %x) +// CHECK-COMMON: [[CAST:%.*]] = bitcast %struct.V* %x to i8* +// CHECK-COMMON-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[CAST]], i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUV@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0) +// CHECK-COMMON-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T* +// CHECK-COMMON-NEXT: ret %struct.T* [[RET]] T* test5(A* x) { return dynamic_cast(x); } -// CHECK-LABEL: define dso_local %struct.T* @"?test5@@YAPAUT@@PAUA@@@Z"(%struct.A* %x) -// CHECK: [[CHECK:%.*]] = icmp eq %struct.A* %x, null -// CHECK-NEXT: br i1 [[CHECK]] -// CHECK: [[VOIDP:%.*]] = bitcast %struct.A* %x to i8* -// CHECK-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A, %struct.A* %x, i32 0, i32 0 -// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4 -// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 -// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4 -// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[VBOFFS]] -// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0) -// CHECK-NEXT: [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T* -// CHECK-NEXT: br label -// CHECK: [[RET:%.*]] = phi %struct.T* -// CHECK-NEXT: ret %struct.T* [[RET]] +// CHECK-COMMON-LABEL: define dso_local %struct.T* @"?test5@@YAPAUT@@PAUA@@@Z"(%struct.A* %x) +// CHECK-COMMON: [[CHECK:%.*]] = icmp eq %struct.A* %x, null +// CHECK-COMMON-NEXT: br i1 [[CHECK]] +// CHECK-COMMON: [[VOIDP:%.*]] = bitcast %struct.A* %x to i8* +// CHECK-COMMON-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A, %struct.A* %x, i32 0, i32 0 +// CHECK-COMMON-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4 +// CHECK-COMMON-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 +// CHECK-COMMON-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4 +// CHECK-COMMON-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[VBOFFS]] +// CHECK-COMMON-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0) +// CHECK-COMMON-NEXT: [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T* +// CHECK-COMMON-NEXT: br label +// CHECK-COMMON: [[RET:%.*]] = phi %struct.T* +// CHECK-COMMON-NEXT: ret %struct.T* [[RET]] T* test6(B* x) { return dynamic_cast(x); } -// CHECK-LABEL: define dso_local %struct.T* @"?test6@@YAPAUT@@PAUB@@@Z"(%struct.B* %x) -// CHECK: [[CHECK:%.*]] = icmp eq %struct.B* %x, null -// CHECK-NEXT: br i1 [[CHECK]] -// CHECK: [[CAST:%.*]] = getelementptr inbounds %struct.B, %struct.B* %x, i32 0, i32 0, i32 0 -// CHECK-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 4 -// CHECK-NEXT: [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR]] to i32** -// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4 -// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 -// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4 -// CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4 -// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[DELTA]] -// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* nonnull [[ADJ]], i32 [[DELTA]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUB@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0) -// CHECK-NEXT: [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T* -// CHECK-NEXT: br label -// CHECK: [[RET:%.*]] = phi %struct.T* -// CHECK-NEXT: ret %struct.T* [[RET]] +// CHECK-COMMON-LABEL: define dso_local %struct.T* @"?test6@@YAPAUT@@PAUB@@@Z"(%struct.B* %x) +// CHECK-COMMON: [[CHECK:%.*]] = icmp eq %struct.B* %x, null +// CHECK-COMMON-NEXT: br i1 [[CHECK]] +// CHECK-COMMON: [[CAST:%.*]] = getelementptr inbounds %struct.B, %struct.B* %x, i32 0, i32 0, i32 0 +// CHECK-COMMON-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 4 +// CHECK-COMMON-NEXT: [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR]] to i32** +// CHECK-COMMON-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4 +// CHECK-COMMON-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 +// CHECK-COMMON-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4 +// CHECK-COMMON-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4 +// CHECK-COMMON-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[DELTA]] +// CHECK-NONNULL: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* nonnull [[ADJ]], i32 [[DELTA]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUB@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0) +// CHECK-NO-NULL: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUB@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0) +// CHECK-COMMON-NEXT: [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T* +// CHECK-COMMON-NEXT: br label +// CHECK-COMMON: [[RET:%.*]] = phi %struct.T* +// CHECK-COMMON-NEXT: ret %struct.T* [[RET]] void* test7(V* x) { return dynamic_cast(x); } -// CHECK-LABEL: define dso_local i8* @"?test7@@YAPAXPAUV@@@Z"(%struct.V* %x) -// CHECK: [[CAST:%.*]] = bitcast %struct.V* %x to i8* -// CHECK-NEXT: [[RET:%.*]] = tail call i8* @__RTCastToVoid(i8* [[CAST]]) -// CHECK-NEXT: ret i8* [[RET]] +// CHECK-COMMON-LABEL: define dso_local i8* @"?test7@@YAPAXPAUV@@@Z"(%struct.V* %x) +// CHECK-COMMON: [[CAST:%.*]] = bitcast %struct.V* %x to i8* +// CHECK-COMMON-NEXT: [[RET:%.*]] = tail call i8* @__RTCastToVoid(i8* [[CAST]]) +// CHECK-COMMON-NEXT: ret i8* [[RET]] void* test8(A* x) { return dynamic_cast(x); } -// CHECK-LABEL: define dso_local i8* @"?test8@@YAPAXPAUA@@@Z"(%struct.A* %x) -// CHECK: [[CHECK:%.*]] = icmp eq %struct.A* %x, null -// CHECK-NEXT: br i1 [[CHECK]] -// CHECK: [[VOIDP:%.*]] = bitcast %struct.A* %x to i8* -// CHECK-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A, %struct.A* %x, i32 0, i32 0 -// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4 -// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 -// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4 -// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[VBOFFS]] -// CHECK-NEXT: [[RES:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]]) -// CHECK-NEXT: br label -// CHECK: [[RET:%.*]] = phi i8* -// CHECK-NEXT: ret i8* [[RET]] +// CHECK-COMMON-LABEL: define dso_local i8* @"?test8@@YAPAXPAUA@@@Z"(%struct.A* %x) +// CHECK-COMMON: [[CHECK:%.*]] = icmp eq %struct.A* %x, null +// CHECK-COMMON-NEXT: br i1 [[CHECK]] +// CHECK-COMMON: [[VOIDP:%.*]] = bitcast %struct.A* %x to i8* +// CHECK-COMMON-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A, %struct.A* %x, i32 0, i32 0 +// CHECK-COMMON-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4 +// CHECK-COMMON-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 +// CHECK-COMMON-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4 +// CHECK-COMMON-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[VBOFFS]] +// CHECK-COMMON-NEXT: [[RES:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]]) +// CHECK-COMMON-NEXT: br label +// CHECK-COMMON: [[RET:%.*]] = phi i8* +// CHECK-COMMON-NEXT: ret i8* [[RET]] void* test9(B* x) { return dynamic_cast(x); } -// CHECK-LABEL: define dso_local i8* @"?test9@@YAPAXPAUB@@@Z"(%struct.B* %x) -// CHECK: [[CHECK:%.*]] = icmp eq %struct.B* %x, null -// CHECK-NEXT: br i1 [[CHECK]] -// CHECK: [[CAST:%.*]] = getelementptr inbounds %struct.B, %struct.B* %x, i32 0, i32 0, i32 0 -// CHECK-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 4 -// CHECK-NEXT: [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR]] to i32** -// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4 -// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 -// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4 -// CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4 -// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[DELTA]] -// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTCastToVoid(i8* nonnull [[ADJ]]) -// CHECK-NEXT: br label -// CHECK: [[RET:%.*]] = phi i8* -// CHECK-NEXT: ret i8* [[RET]] +// CHECK-COMMON-LABEL: define dso_local i8* @"?test9@@YAPAXPAUB@@@Z"(%struct.B* %x) +// CHECK-COMMON: [[CHECK:%.*]] = icmp eq %struct.B* %x, null +// CHECK-COMMON-NEXT: br i1 [[CHECK]] +// CHECK-COMMON: [[CAST:%.*]] = getelementptr inbounds %struct.B, %struct.B* %x, i32 0, i32 0, i32 0 +// CHECK-COMMON-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 4 +// CHECK-COMMON-NEXT: [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR]] to i32** +// CHECK-COMMON-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4 +// CHECK-COMMON-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 +// CHECK-COMMON-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4 +// CHECK-COMMON-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4 +// CHECK-COMMON-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[DELTA]] +// CHECK-NONNULL: [[CALL:%.*]] = tail call i8* @__RTCastToVoid(i8* nonnull [[ADJ]]) +// CHECK-NO-NULL: [[CALL:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]]) +// CHECK-COMMON-NEXT: br label +// CHECK-COMMON: [[RET:%.*]] = phi i8* +// CHECK-COMMON-NEXT: ret i8* [[RET]] namespace PR25606 { struct Cleanup { @@ -134,10 +137,10 @@ Cleanup c; return dynamic_cast(&s); } -// CHECK-LABEL: define dso_local %"struct.PR25606::S3"* @"?f@PR25606@@YAPAUS3@1@AAUS2@1@@Z"( -// CHECK: [[CALL:%.*]] = invoke i8* @__RTDynamicCast +// CHECK-COMMON-LABEL: define dso_local %"struct.PR25606::S3"* @"?f@PR25606@@YAPAUS3@1@AAUS2@1@@Z"( +// CHECK-COMMON: [[CALL:%.*]] = invoke i8* @__RTDynamicCast -// CHECK: [[BC:%.*]] = bitcast i8* [[CALL]] to %"struct.PR25606::S3"* -// CHECK: call x86_thiscallcc void @"??1Cleanup@PR25606@@QAE@XZ"( -// CHECK: ret %"struct.PR25606::S3"* [[BC]] +// CHECK-COMMON: [[BC:%.*]] = bitcast i8* [[CALL]] to %"struct.PR25606::S3"* +// CHECK-COMMON: call x86_thiscallcc void @"??1Cleanup@PR25606@@QAE@XZ"( +// CHECK-NONNULL: ret %"struct.PR25606::S3"* [[BC]] } Index: test/CodeGenCXX/temporaries.cpp =================================================================== --- test/CodeGenCXX/temporaries.cpp +++ test/CodeGenCXX/temporaries.cpp @@ -1,30 +1,31 @@ -// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++11 | FileCheck %s +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++11 | FileCheck %s -check-prefixes=CHECK-COMMON,CHECK-NONNULL +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++11 -fno-delete-null-pointer-checks | FileCheck %s -check-prefixes=CHECK-COMMON,CHECK-NO-NULL namespace PR16263 { const unsigned int n = 1234; extern const int &r = (const int&)n; - // CHECK: @_ZGRN7PR162631rE_ = internal constant i32 1234, - // CHECK: @_ZN7PR162631rE = constant i32* @_ZGRN7PR162631rE_, + // CHECK-COMMON: @_ZGRN7PR162631rE_ = internal constant i32 1234, + // CHECK-COMMON: @_ZN7PR162631rE = constant i32* @_ZGRN7PR162631rE_, extern const int &s = reinterpret_cast(n); - // CHECK: @_ZN7PR16263L1nE = internal constant i32 1234, align 4 - // CHECK: @_ZN7PR162631sE = constant i32* @_ZN7PR16263L1nE, align 8 + // CHECK-COMMON: @_ZN7PR16263L1nE = internal constant i32 1234, align 4 + // CHECK-COMMON: @_ZN7PR162631sE = constant i32* @_ZN7PR16263L1nE, align 8 struct A { int n; }; struct B { int n; }; struct C : A, B {}; extern const A &&a = (A&&)(A&&)(C&&)(C{}); - // CHECK: @_ZGRN7PR162631aE_ = internal global {{.*}} zeroinitializer, - // CHECK: @_ZN7PR162631aE = constant {{.*}} bitcast ({{.*}}* @_ZGRN7PR162631aE_ to + // CHECK-COMMON: @_ZGRN7PR162631aE_ = internal global {{.*}} zeroinitializer, + // CHECK-COMMON: @_ZN7PR162631aE = constant {{.*}} bitcast ({{.*}}* @_ZGRN7PR162631aE_ to extern const int &&t = ((B&&)C{}).n; - // CHECK: @_ZGRN7PR162631tE_ = internal global {{.*}} zeroinitializer, - // CHECK: @_ZN7PR162631tE = constant i32* {{.*}}* @_ZGRN7PR162631tE_ {{.*}} 4 + // CHECK-COMMON: @_ZGRN7PR162631tE_ = internal global {{.*}} zeroinitializer, + // CHECK-COMMON: @_ZN7PR162631tE = constant i32* {{.*}}* @_ZGRN7PR162631tE_ {{.*}} 4 struct D { double d; C c; }; extern const int &&u = (123, static_cast(0, ((D&&)D{}).*&D::c).n); - // CHECK: @_ZGRN7PR162631uE_ = internal global {{.*}} zeroinitializer - // CHECK: @_ZN7PR162631uE = constant i32* {{.*}} @_ZGRN7PR162631uE_ {{.*}} 12 + // CHECK-COMMON: @_ZGRN7PR162631uE_ = internal global {{.*}} zeroinitializer + // CHECK-COMMON: @_ZN7PR162631uE = constant i32* {{.*}} @_ZGRN7PR162631uE_ {{.*}} 12 } namespace PR20227 { @@ -33,20 +34,20 @@ struct C : B {}; A &&a = dynamic_cast(A{}); - // CHECK: @_ZGRN7PR202271aE_ = internal global + // CHECK-COMMON: @_ZGRN7PR202271aE_ = internal global B &&b = dynamic_cast(dynamic_cast(C{})); - // CHECK: @_ZGRN7PR202271bE_ = internal global + // CHECK-COMMON: @_ZGRN7PR202271bE_ = internal global B &&c = static_cast(static_cast(C{})); - // CHECK: @_ZGRN7PR202271cE_ = internal global + // CHECK-COMMON: @_ZGRN7PR202271cE_ = internal global } namespace BraceInit { typedef const int &CIR; CIR x = CIR{3}; - // CHECK: @_ZGRN9BraceInit1xE_ = internal constant i32 3 - // CHECK: @_ZN9BraceInit1xE = constant i32* @_ZGRN9BraceInit1xE_ + // CHECK-COMMON: @_ZGRN9BraceInit1xE_ = internal constant i32 3 + // CHECK-COMMON: @_ZN9BraceInit1xE = constant i32* @_ZGRN9BraceInit1xE_ } struct A { @@ -56,12 +57,12 @@ }; void f1() { - // CHECK: call void @_ZN1AC1Ev - // CHECK: call void @_ZN1AD1Ev + // CHECK-COMMON: call void @_ZN1AC1Ev + // CHECK-COMMON: call void @_ZN1AD1Ev (void)A(); - // CHECK: call void @_ZN1AC1Ev - // CHECK: call void @_ZN1AD1Ev + // CHECK-COMMON: call void @_ZN1AC1Ev + // CHECK-COMMON: call void @_ZN1AD1Ev A().f(); } @@ -74,8 +75,8 @@ B g(); void f2() { - // CHECK-NOT: call void @_ZN1BC1Ev - // CHECK: call void @_ZN1BD1Ev + // CHECK-COMMON-NOT: call void @_ZN1BC1Ev + // CHECK-COMMON: call void @_ZN1BD1Ev (void)g(); } @@ -88,9 +89,9 @@ }; void f3() { - // CHECK: call void @_ZN1CC1Ev - // CHECK: call void @_ZN1CD1Ev - // CHECK: call void @_ZN1CD1Ev + // CHECK-COMMON: call void @_ZN1CC1Ev + // CHECK-COMMON: call void @_ZN1CD1Ev + // CHECK-COMMON: call void @_ZN1CD1Ev C().f(); } @@ -103,9 +104,9 @@ }; void f4() { - // CHECK: call void @_ZN1DC1Ev - // CHECK: call void @_ZN1DD1Ev - // CHECK: call void @_ZN1DD1Ev + // CHECK-COMMON: call void @_ZN1DC1Ev + // CHECK-COMMON: call void @_ZN1DD1Ev + // CHECK-COMMON: call void @_ZN1DD1Ev D()(); } @@ -118,16 +119,16 @@ }; void f5() { - // CHECK: call void @_ZN1EC1Ev - // CHECK: call void @_ZN1EC1Ev - // CHECK: call void @_ZN1ED1Ev - // CHECK: call void @_ZN1ED1Ev - // CHECK: call void @_ZN1ED1Ev + // CHECK-COMMON: call void @_ZN1EC1Ev + // CHECK-COMMON: call void @_ZN1EC1Ev + // CHECK-COMMON: call void @_ZN1ED1Ev + // CHECK-COMMON: call void @_ZN1ED1Ev + // CHECK-COMMON: call void @_ZN1ED1Ev E() + E(); - // CHECK: call void @_ZN1EC1Ev - // CHECK: call void @_ZN1ED1Ev - // CHECK: call void @_ZN1ED1Ev + // CHECK-COMMON: call void @_ZN1EC1Ev + // CHECK-COMMON: call void @_ZN1ED1Ev + // CHECK-COMMON: call void @_ZN1ED1Ev !E(); } @@ -138,8 +139,8 @@ }; void f6() { - // CHECK: call void @_ZN1FC1Ev - // CHECK: call void @_ZN1FD1Ev + // CHECK-COMMON: call void @_ZN1FC1Ev + // CHECK-COMMON: call void @_ZN1FD1Ev F().f(); } @@ -153,16 +154,16 @@ void a(const A&); void f7() { - // CHECK: call void @_ZN1AC1Ev - // CHECK: call void @_Z1aRK1A - // CHECK: call void @_ZN1AD1Ev + // CHECK-COMMON: call void @_ZN1AC1Ev + // CHECK-COMMON: call void @_Z1aRK1A + // CHECK-COMMON: call void @_ZN1AD1Ev a(A()); - // CHECK: call void @_ZN1GC1Ev - // CHECK: call void @_ZN1Gcv1AEv - // CHECK: call void @_Z1aRK1A - // CHECK: call void @_ZN1AD1Ev - // CHECK: call void @_ZN1GD1Ev + // CHECK-COMMON: call void @_ZN1GC1Ev + // CHECK-COMMON: call void @_ZN1Gcv1AEv + // CHECK-COMMON: call void @_Z1aRK1A + // CHECK-COMMON: call void @_ZN1AD1Ev + // CHECK-COMMON: call void @_ZN1GD1Ev a(G()); } @@ -185,16 +186,16 @@ }; B::B() - // CHECK: call void @_ZN6PR50771AC1Ev - // CHECK: call i32 @_ZN6PR50771A1fEv - // CHECK: call void @_ZN6PR50771AD1Ev + // CHECK-COMMON: call void @_ZN6PR50771AC1Ev + // CHECK-COMMON: call i32 @_ZN6PR50771A1fEv + // CHECK-COMMON: call void @_ZN6PR50771AD1Ev : a1(A().f()) - // CHECK: call void @_ZN6PR50771AC1Ev - // CHECK: call i32 @_ZN6PR50771gERKNS_1AE - // CHECK: call void @_ZN6PR50771AD1Ev + // CHECK-COMMON: call void @_ZN6PR50771AC1Ev + // CHECK-COMMON: call i32 @_ZN6PR50771gERKNS_1AE + // CHECK-COMMON: call void @_ZN6PR50771AD1Ev , a2(g(A())) { - // CHECK: call void @_ZN6PR50771fEv + // CHECK-COMMON: call void @_ZN6PR50771fEv f(); } @@ -205,20 +206,20 @@ }; C::C() - // CHECK: call void @_ZN6PR50771BC1Ev + // CHECK-COMMON: call void @_ZN6PR50771BC1Ev : b(B()) { - // CHECK: call void @_ZN6PR50771fEv + // CHECK-COMMON: call void @_ZN6PR50771fEv f(); - // CHECK: call void @_ZN6PR50771BD1Ev + // CHECK-COMMON: call void @_ZN6PR50771BD1Ev } } A f8() { - // CHECK: call void @_ZN1AC1Ev - // CHECK-NOT: call void @_ZN1AD1Ev + // CHECK-COMMON: call void @_ZN1AC1Ev + // CHECK-COMMON-NOT: call void @_ZN1AD1Ev return A(); - // CHECK: ret void + // CHECK-COMMON: ret void } struct H { @@ -228,28 +229,28 @@ }; void f9(H h) { - // CHECK: call void @_ZN1HC1Ev - // CHECK: call void @_Z2f91H - // CHECK: call void @_ZN1HD1Ev + // CHECK-COMMON: call void @_ZN1HC1Ev + // CHECK-COMMON: call void @_Z2f91H + // CHECK-COMMON: call void @_ZN1HD1Ev f9(H()); - // CHECK: call void @_ZN1HC1ERKS_ - // CHECK: call void @_Z2f91H - // CHECK: call void @_ZN1HD1Ev + // CHECK-COMMON: call void @_ZN1HC1ERKS_ + // CHECK-COMMON: call void @_Z2f91H + // CHECK-COMMON: call void @_ZN1HD1Ev f9(h); } void f10(const H&); void f11(H h) { - // CHECK: call void @_ZN1HC1Ev - // CHECK: call void @_Z3f10RK1H - // CHECK: call void @_ZN1HD1Ev + // CHECK-COMMON: call void @_ZN1HC1Ev + // CHECK-COMMON: call void @_Z3f10RK1H + // CHECK-COMMON: call void @_ZN1HD1Ev f10(H()); - // CHECK: call void @_Z3f10RK1H - // CHECK-NOT: call void @_ZN1HD1Ev - // CHECK: ret void + // CHECK-COMMON: call void @_Z3f10RK1H + // CHECK-COMMON-NOT: call void @_ZN1HD1Ev + // CHECK-COMMON: ret void f10(h); } @@ -259,11 +260,11 @@ ~I(); }; -// CHECK: _Z3f12v +// CHECK-COMMON: _Z3f12v I f12() { - // CHECK: call void @_ZN1IC1EPKc - // CHECK-NOT: call void @_ZN1ID1Ev - // CHECK: ret void + // CHECK-COMMON: call void @_ZN1IC1EPKc + // CHECK-COMMON-NOT: call void @_ZN1ID1Ev + // CHECK-COMMON: ret void return "Hello"; } @@ -276,22 +277,22 @@ }; void f(S, int); - // CHECK-LABEL: define void @_ZN6PR58671gEv + // CHECK-COMMON-LABEL: define void @_ZN6PR58671gEv void g() { - // CHECK: call void @_ZN6PR58671SC1Ev - // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi - // CHECK-NEXT: call void @_ZN6PR58671SD1Ev - // CHECK-NEXT: ret void + // CHECK-COMMON: call void @_ZN6PR58671SC1Ev + // CHECK-COMMON-NEXT: call void @_ZN6PR58671fENS_1SEi + // CHECK-COMMON-NEXT: call void @_ZN6PR58671SD1Ev + // CHECK-COMMON-NEXT: ret void (f)(S(), 0); } - // CHECK-LABEL: define linkonce_odr void @_ZN6PR58672g2IiEEvT_ + // CHECK-COMMON-LABEL: define linkonce_odr void @_ZN6PR58672g2IiEEvT_ template void g2(T) { - // CHECK: call void @_ZN6PR58671SC1Ev - // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi - // CHECK-NEXT: call void @_ZN6PR58671SD1Ev - // CHECK-NEXT: ret void + // CHECK-COMMON: call void @_ZN6PR58671SC1Ev + // CHECK-COMMON-NEXT: call void @_ZN6PR58671fENS_1SEi + // CHECK-COMMON-NEXT: call void @_ZN6PR58671SD1Ev + // CHECK-COMMON-NEXT: ret void (f)(S(), 0); } @@ -306,11 +307,11 @@ struct B { operator A(); }; - // CHECK-LABEL: define weak_odr void @_ZN6PR61992f2IiEENS_1AET_ + // CHECK-COMMON-LABEL: define weak_odr void @_ZN6PR61992f2IiEENS_1AET_ template A f2(T) { B b; - // CHECK: call void @_ZN6PR61991BcvNS_1AEEv - // CHECK-NEXT: ret void + // CHECK-COMMON: call void @_ZN6PR61991BcvNS_1AEEv + // CHECK-COMMON-NEXT: ret void return b; } @@ -328,12 +329,12 @@ int& f(int); -// CHECK-LABEL: define void @_ZN3T121gEv +// CHECK-COMMON-LABEL: define void @_ZN3T121gEv void g() { - // CHECK: call void @_ZN3T121AC1Ev - // CHECK-NEXT: call i32 @_ZN3T121A1fEv( - // CHECK-NEXT: call dereferenceable({{[0-9]+}}) i32* @_ZN3T121fEi( - // CHECK-NEXT: call void @_ZN3T121AD1Ev( + // CHECK-COMMON: call void @_ZN3T121AC1Ev + // CHECK-COMMON-NEXT: call i32 @_ZN3T121A1fEv( + // CHECK-COMMON-NEXT: call dereferenceable({{[0-9]+}}) i32* @_ZN3T121fEi( + // CHECK-COMMON-NEXT: call void @_ZN3T121AD1Ev( int& i = f(A().f()); } @@ -347,7 +348,8 @@ struct D; D& zed(B); void foobar() { - // CHECK: call nonnull %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE + // CHECK-NONNULL: call nonnull %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE + // CHECK-NO-NULL: call %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE zed(foo); } } @@ -361,12 +363,12 @@ void f(X); - // CHECK: void @_ZN18UserConvertToValue1gEv() + // CHECK-COMMON: void @_ZN18UserConvertToValue1gEv() void g() { - // CHECK: call void @_ZN18UserConvertToValue1XC1Ei - // CHECK: call void @_ZN18UserConvertToValue1fENS_1XE - // CHECK: call void @_ZN18UserConvertToValue1XD1Ev - // CHECK: ret void + // CHECK-COMMON: call void @_ZN18UserConvertToValue1XC1Ei + // CHECK-COMMON: call void @_ZN18UserConvertToValue1fENS_1XE + // CHECK-COMMON: call void @_ZN18UserConvertToValue1XD1Ev + // CHECK-COMMON: ret void f(1); } } @@ -375,17 +377,17 @@ struct A { ~A(); }; struct B { int i; ~B(); }; struct C { int C::*pm; ~C(); }; - // CHECK-LABEL: define void @_ZN6PR75563fooEv() + // CHECK-COMMON-LABEL: define void @_ZN6PR75563fooEv() void foo() { - // CHECK: call void @_ZN6PR75561AD1Ev + // CHECK-COMMON: call void @_ZN6PR75561AD1Ev A(); - // CHECK: call void @llvm.memset.p0i8.i64 - // CHECK: call void @_ZN6PR75561BD1Ev + // CHECK-COMMON: call void @llvm.memset.p0i8.i64 + // CHECK-COMMON: call void @_ZN6PR75561BD1Ev B(); - // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 - // CHECK: call void @_ZN6PR75561CD1Ev + // CHECK-COMMON: call void @llvm.memcpy.p0i8.p0i8.i64 + // CHECK-COMMON: call void @_ZN6PR75561CD1Ev C(); - // CHECK-NEXT: ret void + // CHECK-COMMON-NEXT: ret void } } @@ -400,142 +402,142 @@ A fooA(); void takeA(A a); - // CHECK-LABEL: define void @_ZN7Elision5test0Ev() + // CHECK-COMMON-LABEL: define void @_ZN7Elision5test0Ev() void test0() { - // CHECK: [[I:%.*]] = alloca [[A:%.*]], align 8 - // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8 - // CHECK-NEXT: [[T0:%.*]] = alloca [[A]], align 8 - // CHECK-NEXT: [[K:%.*]] = alloca [[A]], align 8 - // CHECK-NEXT: [[T1:%.*]] = alloca [[A]], align 8 - - // CHECK-NEXT: call void @_ZN7Elision3fooEv() - // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[I]]) + // CHECK-COMMON: [[I:%.*]] = alloca [[A:%.*]], align 8 + // CHECK-COMMON-NEXT: [[J:%.*]] = alloca [[A]], align 8 + // CHECK-COMMON-NEXT: [[T0:%.*]] = alloca [[A]], align 8 + // CHECK-COMMON-NEXT: [[K:%.*]] = alloca [[A]], align 8 + // CHECK-COMMON-NEXT: [[T1:%.*]] = alloca [[A]], align 8 + + // CHECK-COMMON-NEXT: call void @_ZN7Elision3fooEv() + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[I]]) A i = (foo(), A()); - // CHECK-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[T0]]) - // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[J]]) - // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[T0]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[J]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]]) A j = (fooA(), A()); - // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[T1]]) - // CHECK-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[K]]) - // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T1]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[T1]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[K]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T1]]) A k = (A(), fooA()); - // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[K]]) - // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[J]]) - // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[K]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[J]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]]) } - // CHECK-LABEL: define void @_ZN7Elision5test1EbNS_1AE( + // CHECK-COMMON-LABEL: define void @_ZN7Elision5test1EbNS_1AE( void test1(bool c, A x) { - // CHECK: [[I:%.*]] = alloca [[A]], align 8 - // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8 + // CHECK-COMMON: [[I:%.*]] = alloca [[A]], align 8 + // CHECK-COMMON-NEXT: [[J:%.*]] = alloca [[A]], align 8 - // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[I]]) - // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[I]], [[A]]* dereferenceable({{[0-9]+}}) [[X:%.*]]) + // CHECK-COMMON: call void @_ZN7Elision1AC1Ev([[A]]* [[I]]) + // CHECK-COMMON: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[I]], [[A]]* dereferenceable({{[0-9]+}}) [[X:%.*]]) A i = (c ? A() : x); - // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[J]], [[A]]* dereferenceable({{[0-9]+}}) [[X]]) - // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[J]]) + // CHECK-COMMON: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[J]], [[A]]* dereferenceable({{[0-9]+}}) [[X]]) + // CHECK-COMMON: call void @_ZN7Elision1AC1Ev([[A]]* [[J]]) A j = (c ? x : A()); - // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[J]]) - // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]]) + // CHECK-COMMON: call void @_ZN7Elision1AD1Ev([[A]]* [[J]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]]) } - // CHECK: define void @_ZN7Elision5test2Ev([[A]]* noalias sret + // CHECK-COMMON: define void @_ZN7Elision5test2Ev([[A]]* noalias sret A test2() { - // CHECK: call void @_ZN7Elision3fooEv() - // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]]) - // CHECK-NEXT: ret void + // CHECK-COMMON: call void @_ZN7Elision3fooEv() + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]]) + // CHECK-COMMON-NEXT: ret void return (foo(), A()); } - // CHECK: define void @_ZN7Elision5test3EiNS_1AE([[A]]* noalias sret + // CHECK-COMMON: define void @_ZN7Elision5test3EiNS_1AE([[A]]* noalias sret A test3(int v, A x) { if (v < 5) - // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]]) - // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* dereferenceable({{[0-9]+}}) [[X:%.*]]) + // CHECK-COMMON: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]]) + // CHECK-COMMON: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* dereferenceable({{[0-9]+}}) [[X:%.*]]) return (v < 0 ? A() : x); else - // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* dereferenceable({{[0-9]+}}) [[X]]) - // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[RET]]) + // CHECK-COMMON: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* dereferenceable({{[0-9]+}}) [[X]]) + // CHECK-COMMON: call void @_ZN7Elision1AC1Ev([[A]]* [[RET]]) return (v > 10 ? x : A()); - // CHECK: ret void + // CHECK-COMMON: ret void } - // CHECK-LABEL: define void @_ZN7Elision5test4Ev() + // CHECK-COMMON-LABEL: define void @_ZN7Elision5test4Ev() void test4() { - // CHECK: [[X:%.*]] = alloca [[A]], align 8 - // CHECK-NEXT: [[XS:%.*]] = alloca [2 x [[A]]], align 16 + // CHECK-COMMON: [[X:%.*]] = alloca [[A]], align 8 + // CHECK-COMMON-NEXT: [[XS:%.*]] = alloca [2 x [[A]]], align 16 - // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[X]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[X]]) A x; - // CHECK-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]], [2 x [[A]]]* [[XS]], i64 0, i64 0 - // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[XS0]]) - // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[XS0]], i64 1 - // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[XS1]], [[A]]* dereferenceable({{[0-9]+}}) [[X]]) + // CHECK-COMMON-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]], [2 x [[A]]]* [[XS]], i64 0, i64 0 + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[XS0]]) + // CHECK-COMMON-NEXT: [[XS1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[XS0]], i64 1 + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[XS1]], [[A]]* dereferenceable({{[0-9]+}}) [[X]]) A xs[] = { A(), x }; - // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [2 x [[A]]], [2 x [[A]]]* [[XS]], i32 0, i32 0 - // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 2 - // CHECK-NEXT: br label - // CHECK: [[AFTER:%.*]] = phi [[A]]* - // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1 - // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[CUR]]) - // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]] - // CHECK-NEXT: br i1 [[T0]], + // CHECK-COMMON-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [2 x [[A]]], [2 x [[A]]]* [[XS]], i32 0, i32 0 + // CHECK-COMMON-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 2 + // CHECK-COMMON-NEXT: br label + // CHECK-COMMON: [[AFTER:%.*]] = phi [[A]]* + // CHECK-COMMON-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1 + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[CUR]]) + // CHECK-COMMON-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]] + // CHECK-COMMON-NEXT: br i1 [[T0]], - // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[X]]) + // CHECK-COMMON: call void @_ZN7Elision1AD1Ev([[A]]* [[X]]) } // rdar://problem/8433352 - // CHECK: define void @_ZN7Elision5test5Ev([[A]]* noalias sret + // CHECK-COMMON: define void @_ZN7Elision5test5Ev([[A]]* noalias sret struct B { A a; B(); }; A test5() { - // CHECK: [[AT0:%.*]] = alloca [[A]], align 8 - // CHECK-NEXT: [[BT0:%.*]] = alloca [[B:%.*]], align 8 - // CHECK-NEXT: [[X:%.*]] = alloca [[A]], align 8 - // CHECK-NEXT: [[BT1:%.*]] = alloca [[B]], align 8 - // CHECK-NEXT: [[BT2:%.*]] = alloca [[B]], align 8 - - // CHECK: call void @_ZN7Elision1BC1Ev([[B]]* [[BT0]]) - // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]], [[B]]* [[BT0]], i32 0, i32 0 - // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[AT0]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]]) - // CHECK-NEXT: call void @_ZN7Elision5takeAENS_1AE([[A]]* [[AT0]]) - // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[AT0]]) - // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT0]]) + // CHECK-COMMON: [[AT0:%.*]] = alloca [[A]], align 8 + // CHECK-COMMON-NEXT: [[BT0:%.*]] = alloca [[B:%.*]], align 8 + // CHECK-COMMON-NEXT: [[X:%.*]] = alloca [[A]], align 8 + // CHECK-COMMON-NEXT: [[BT1:%.*]] = alloca [[B]], align 8 + // CHECK-COMMON-NEXT: [[BT2:%.*]] = alloca [[B]], align 8 + + // CHECK-COMMON: call void @_ZN7Elision1BC1Ev([[B]]* [[BT0]]) + // CHECK-COMMON-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]], [[B]]* [[BT0]], i32 0, i32 0 + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[AT0]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision5takeAENS_1AE([[A]]* [[AT0]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[AT0]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT0]]) takeA(B().a); - // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT1]]) - // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]], [[B]]* [[BT1]], i32 0, i32 0 - // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[X]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]]) - // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT1]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT1]]) + // CHECK-COMMON-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]], [[B]]* [[BT1]], i32 0, i32 0 + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[X]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT1]]) A x = B().a; - // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT2]]) - // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]], [[B]]* [[BT2]], i32 0, i32 0 - // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET:%.*]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]]) - // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT2]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT2]]) + // CHECK-COMMON-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]], [[B]]* [[BT2]], i32 0, i32 0 + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET:%.*]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT2]]) return B().a; - // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[X]]) + // CHECK-COMMON: call void @_ZN7Elision1AD1Ev([[A]]* [[X]]) } // Reduced from webkit. - // CHECK: define void @_ZN7Elision5test6EPKNS_1CE([[C:%.*]]* + // CHECK-COMMON: define void @_ZN7Elision5test6EPKNS_1CE([[C:%.*]]* struct C { operator A() const; }; void test6(const C *x) { - // CHECK: [[T0:%.*]] = alloca [[A]], align 8 - // CHECK: [[X:%.*]] = load [[C]]*, [[C]]** {{%.*}}, align 8 - // CHECK-NEXT: call void @_ZNK7Elision1CcvNS_1AEEv([[A]]* sret [[T0]], [[C]]* [[X]]) - // CHECK-NEXT: call void @_ZNK7Elision1A3fooEv([[A]]* [[T0]]) - // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]]) - // CHECK-NEXT: ret void + // CHECK-COMMON: [[T0:%.*]] = alloca [[A]], align 8 + // CHECK-COMMON: [[X:%.*]] = load [[C]]*, [[C]]** {{%.*}}, align 8 + // CHECK-COMMON-NEXT: call void @_ZNK7Elision1CcvNS_1AEEv([[A]]* sret [[T0]], [[C]]* [[X]]) + // CHECK-COMMON-NEXT: call void @_ZNK7Elision1A3fooEv([[A]]* [[T0]]) + // CHECK-COMMON-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]]) + // CHECK-COMMON-NEXT: ret void A(*x).foo(); } } @@ -543,29 +545,29 @@ namespace PR8623 { struct A { A(int); ~A(); }; - // CHECK-LABEL: define void @_ZN6PR86233fooEb( + // CHECK-COMMON-LABEL: define void @_ZN6PR86233fooEb( void foo(bool b) { - // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1 - // CHECK-NEXT: [[LCONS:%.*]] = alloca i1 - // CHECK-NEXT: [[RCONS:%.*]] = alloca i1 - // CHECK: store i1 false, i1* [[LCONS]] - // CHECK-NEXT: store i1 false, i1* [[RCONS]] - // CHECK-NEXT: br i1 - // CHECK: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 2) - // CHECK-NEXT: store i1 true, i1* [[LCONS]] - // CHECK-NEXT: br label - // CHECK: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 3) - // CHECK-NEXT: store i1 true, i1* [[RCONS]] - // CHECK-NEXT: br label - // CHECK: load i1, i1* [[RCONS]] - // CHECK-NEXT: br i1 - // CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]]) - // CHECK-NEXT: br label - // CHECK: load i1, i1* [[LCONS]] - // CHECK-NEXT: br i1 - // CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]]) - // CHECK-NEXT: br label - // CHECK: ret void + // CHECK-COMMON: [[TMP:%.*]] = alloca [[A:%.*]], align 1 + // CHECK-COMMON-NEXT: [[LCONS:%.*]] = alloca i1 + // CHECK-COMMON-NEXT: [[RCONS:%.*]] = alloca i1 + // CHECK-COMMON: store i1 false, i1* [[LCONS]] + // CHECK-COMMON-NEXT: store i1 false, i1* [[RCONS]] + // CHECK-COMMON-NEXT: br i1 + // CHECK-COMMON: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 2) + // CHECK-COMMON-NEXT: store i1 true, i1* [[LCONS]] + // CHECK-COMMON-NEXT: br label + // CHECK-COMMON: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 3) + // CHECK-COMMON-NEXT: store i1 true, i1* [[RCONS]] + // CHECK-COMMON-NEXT: br label + // CHECK-COMMON: load i1, i1* [[RCONS]] + // CHECK-COMMON-NEXT: br i1 + // CHECK-COMMON: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]]) + // CHECK-COMMON-NEXT: br label + // CHECK-COMMON: load i1, i1* [[LCONS]] + // CHECK-COMMON-NEXT: br i1 + // CHECK-COMMON: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]]) + // CHECK-COMMON-NEXT: br label + // CHECK-COMMON: ret void b ? A(2) : A(3); } } @@ -573,17 +575,17 @@ namespace PR11365 { struct A { A(); ~A(); }; - // CHECK-LABEL: define void @_ZN7PR113653fooEv( + // CHECK-COMMON-LABEL: define void @_ZN7PR113653fooEv( void foo() { - // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [3 x [[A:%.*]]], [3 x [[A:%.*]]]* {{.*}}, i32 0, i32 0 - // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 3 - // CHECK-NEXT: br label - - // CHECK: [[PHI:%.*]] = phi - // CHECK-NEXT: [[ELEM:%.*]] = getelementptr inbounds [[A]], [[A]]* [[PHI]], i64 -1 - // CHECK-NEXT: call void @_ZN7PR113651AD1Ev([[A]]* [[ELEM]]) - // CHECK-NEXT: icmp eq [[A]]* [[ELEM]], [[BEGIN]] - // CHECK-NEXT: br i1 + // CHECK-COMMON: [[BEGIN:%.*]] = getelementptr inbounds [3 x [[A:%.*]]], [3 x [[A:%.*]]]* {{.*}}, i32 0, i32 0 + // CHECK-COMMON-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 3 + // CHECK-COMMON-NEXT: br label + + // CHECK-COMMON: [[PHI:%.*]] = phi + // CHECK-COMMON-NEXT: [[ELEM:%.*]] = getelementptr inbounds [[A]], [[A]]* [[PHI]], i64 -1 + // CHECK-COMMON-NEXT: call void @_ZN7PR113651AD1Ev([[A]]* [[ELEM]]) + // CHECK-COMMON-NEXT: icmp eq [[A]]* [[ELEM]], [[BEGIN]] + // CHECK-COMMON-NEXT: br i1 (void) (A [3]) {}; } } @@ -592,21 +594,21 @@ struct A { ~A(); }; struct B { A operator=(const B&); }; struct C : B { B b1, b2; }; - // CHECK-LABEL: define void @_ZN12AssignmentOp1fE + // CHECK-COMMON-LABEL: define void @_ZN12AssignmentOp1fE void f(C &c1, const C &c2) { - // CHECK: call {{.*}} @_ZN12AssignmentOp1CaSERKS0_( + // CHECK-COMMON: call {{.*}} @_ZN12AssignmentOp1CaSERKS0_( c1 = c2; } // Ensure that each 'A' temporary is destroyed before the next subobject is // copied. - // CHECK: define {{.*}} @_ZN12AssignmentOp1CaSERKS0_( - // CHECK: call {{.*}} @_ZN12AssignmentOp1BaSERKS - // CHECK: call {{.*}} @_ZN12AssignmentOp1AD1Ev( - // CHECK: call {{.*}} @_ZN12AssignmentOp1BaSERKS - // CHECK: call {{.*}} @_ZN12AssignmentOp1AD1Ev( - // CHECK: call {{.*}} @_ZN12AssignmentOp1BaSERKS - // CHECK: call {{.*}} @_ZN12AssignmentOp1AD1Ev( + // CHECK-COMMON: define {{.*}} @_ZN12AssignmentOp1CaSERKS0_( + // CHECK-COMMON: call {{.*}} @_ZN12AssignmentOp1BaSERKS + // CHECK-COMMON: call {{.*}} @_ZN12AssignmentOp1AD1Ev( + // CHECK-COMMON: call {{.*}} @_ZN12AssignmentOp1BaSERKS + // CHECK-COMMON: call {{.*}} @_ZN12AssignmentOp1AD1Ev( + // CHECK-COMMON: call {{.*}} @_ZN12AssignmentOp1BaSERKS + // CHECK-COMMON: call {{.*}} @_ZN12AssignmentOp1AD1Ev( } namespace BindToSubobject { @@ -618,26 +620,26 @@ void f(), g(); - // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1aE_) - // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1aE_ to i8*), i8* @__dso_handle) - // CHECK: store i32* getelementptr inbounds ({{.*}} @_ZGRN15BindToSubobject1aE_, i32 0, i32 0), i32** @_ZN15BindToSubobject1aE, align 8 + // CHECK-COMMON: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1aE_) + // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1aE_ to i8*), i8* @__dso_handle) + // CHECK-COMMON: store i32* getelementptr inbounds ({{.*}} @_ZGRN15BindToSubobject1aE_, i32 0, i32 0), i32** @_ZN15BindToSubobject1aE, align 8 int &&a = A().a; - // CHECK: call void @_ZN15BindToSubobject1fEv() - // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1bE_) - // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1bE_ to i8*), i8* @__dso_handle) - // CHECK: store i32* getelementptr inbounds ({{.*}} @_ZGRN15BindToSubobject1bE_, i32 0, i32 0), i32** @_ZN15BindToSubobject1bE, align 8 + // CHECK-COMMON: call void @_ZN15BindToSubobject1fEv() + // CHECK-COMMON: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1bE_) + // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1bE_ to i8*), i8* @__dso_handle) + // CHECK-COMMON: store i32* getelementptr inbounds ({{.*}} @_ZGRN15BindToSubobject1bE_, i32 0, i32 0), i32** @_ZN15BindToSubobject1bE, align 8 int &&b = (f(), A().a); int A::*h(); - // CHECK: call void @_ZN15BindToSubobject1fEv() - // CHECK: call void @_ZN15BindToSubobject1gEv() - // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1cE_) - // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1cE_ to i8*), i8* @__dso_handle) - // CHECK: call {{.*}} @_ZN15BindToSubobject1hE - // CHECK: getelementptr - // CHECK: store i32* {{.*}}, i32** @_ZN15BindToSubobject1cE, align 8 + // CHECK-COMMON: call void @_ZN15BindToSubobject1fEv() + // CHECK-COMMON: call void @_ZN15BindToSubobject1gEv() + // CHECK-COMMON: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1cE_) + // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1cE_ to i8*), i8* @__dso_handle) + // CHECK-COMMON: call {{.*}} @_ZN15BindToSubobject1hE + // CHECK-COMMON: getelementptr + // CHECK-COMMON: store i32* {{.*}}, i32** @_ZN15BindToSubobject1cE, align 8 int &&c = (f(), (g(), A().*h())); struct B { @@ -645,11 +647,11 @@ A a; }; - // CHECK: call void @_ZN15BindToSubobject1BC1Ev({{.*}} @_ZGRN15BindToSubobject1dE_) - // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1BD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1dE_ to i8*), i8* @__dso_handle) - // CHECK: call {{.*}} @_ZN15BindToSubobject1hE - // CHECK: getelementptr {{.*}} getelementptr - // CHECK: store i32* {{.*}}, i32** @_ZN15BindToSubobject1dE, align 8 + // CHECK-COMMON: call void @_ZN15BindToSubobject1BC1Ev({{.*}} @_ZGRN15BindToSubobject1dE_) + // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1BD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1dE_ to i8*), i8* @__dso_handle) + // CHECK-COMMON: call {{.*}} @_ZN15BindToSubobject1hE + // CHECK-COMMON: getelementptr {{.*}} getelementptr + // CHECK-COMMON: store i32* {{.*}}, i32** @_ZN15BindToSubobject1dE, align 8 int &&d = (B().a).*h(); } @@ -657,11 +659,11 @@ struct S { int a : 5; ~S(); }; // Do not lifetime extend the S() temporary here. - // CHECK: alloca - // CHECK: call {{.*}}memset - // CHECK: store i32 {{.*}}, i32* @_ZGRN8Bitfield1rE_ - // CHECK: call void @_ZN8Bitfield1SD1 - // CHECK: store i32* @_ZGRN8Bitfield1rE_, i32** @_ZN8Bitfield1rE, align 8 + // CHECK-COMMON: alloca + // CHECK-COMMON: call {{.*}}memset + // CHECK-COMMON: store i32 {{.*}}, i32* @_ZGRN8Bitfield1rE_ + // CHECK-COMMON: call void @_ZN8Bitfield1SD1 + // CHECK-COMMON: store i32* @_ZGRN8Bitfield1rE_, i32** @_ZN8Bitfield1rE, align 8 int &&r = S().a; } @@ -672,16 +674,16 @@ vi4a v; vi4b w; }; - // CHECK: alloca - // CHECK: extractelement - // CHECK: store i32 {{.*}}, i32* @_ZGRN6Vector1rE_ - // CHECK: store i32* @_ZGRN6Vector1rE_, i32** @_ZN6Vector1rE, + // CHECK-COMMON: alloca + // CHECK-COMMON: extractelement + // CHECK-COMMON: store i32 {{.*}}, i32* @_ZGRN6Vector1rE_ + // CHECK-COMMON: store i32* @_ZGRN6Vector1rE_, i32** @_ZN6Vector1rE, int &&r = S().v[1]; - // CHECK: alloca - // CHECK: extractelement - // CHECK: store i32 {{.*}}, i32* @_ZGRN6Vector1sE_ - // CHECK: store i32* @_ZGRN6Vector1sE_, i32** @_ZN6Vector1sE, + // CHECK-COMMON: alloca + // CHECK-COMMON: extractelement + // CHECK-COMMON: store i32 {{.*}}, i32* @_ZGRN6Vector1sE_ + // CHECK-COMMON: store i32* @_ZGRN6Vector1sE_, i32** @_ZN6Vector1sE, int &&s = S().w[1]; // FIXME PR16204: The following code leads to an assertion in Sema. //int &&s = S().w.y; @@ -691,15 +693,15 @@ struct A { A(int); ~A(); }; void g(); - // CHECK-LABEL: define void @_ZN24ImplicitTemporaryCleanup1fEv( + // CHECK-COMMON-LABEL: define void @_ZN24ImplicitTemporaryCleanup1fEv( void f() { - // CHECK: call {{.*}} @_ZN24ImplicitTemporaryCleanup1AC1Ei( + // CHECK-COMMON: call {{.*}} @_ZN24ImplicitTemporaryCleanup1AC1Ei( A &&a = 0; - // CHECK: call {{.*}} @_ZN24ImplicitTemporaryCleanup1gEv( + // CHECK-COMMON: call {{.*}} @_ZN24ImplicitTemporaryCleanup1gEv( g(); - // CHECK: call {{.*}} @_ZN24ImplicitTemporaryCleanup1AD1Ev( + // CHECK-COMMON: call {{.*}} @_ZN24ImplicitTemporaryCleanup1AD1Ev( } } @@ -712,70 +714,70 @@ E &&e1 = { A(), B(), D().c }; - // CHECK: call void @_ZN17MultipleExtension1AC1Ev({{.*}} @[[TEMPA:_ZGRN17MultipleExtension2e1E.*]]) - // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1AD1Ev {{.*}} @[[TEMPA]] - // CHECK: store {{.*}} @[[TEMPA]], {{.*}} getelementptr inbounds ({{.*}} @[[TEMPE:_ZGRN17MultipleExtension2e1E.*]], i32 0, i32 0) + // CHECK-COMMON: call void @_ZN17MultipleExtension1AC1Ev({{.*}} @[[TEMPA:_ZGRN17MultipleExtension2e1E.*]]) + // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1AD1Ev {{.*}} @[[TEMPA]] + // CHECK-COMMON: store {{.*}} @[[TEMPA]], {{.*}} getelementptr inbounds ({{.*}} @[[TEMPE:_ZGRN17MultipleExtension2e1E.*]], i32 0, i32 0) - // CHECK: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds ({{.*}} @[[TEMPE]], i32 0, i32 1)) + // CHECK-COMMON: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds ({{.*}} @[[TEMPE]], i32 0, i32 1)) - // CHECK: call void @_ZN17MultipleExtension1DC1Ev({{.*}} @[[TEMPD:_ZGRN17MultipleExtension2e1E.*]]) - // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1DD1Ev {{.*}} @[[TEMPD]] - // CHECK: store {{.*}} @[[TEMPD]], {{.*}} getelementptr inbounds ({{.*}} @[[TEMPE]], i32 0, i32 2) - // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1ED1Ev {{.*}} @[[TEMPE]] - // CHECK: store {{.*}} @[[TEMPE]], %"struct.MultipleExtension::E"** @_ZN17MultipleExtension2e1E, align 8 + // CHECK-COMMON: call void @_ZN17MultipleExtension1DC1Ev({{.*}} @[[TEMPD:_ZGRN17MultipleExtension2e1E.*]]) + // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1DD1Ev {{.*}} @[[TEMPD]] + // CHECK-COMMON: store {{.*}} @[[TEMPD]], {{.*}} getelementptr inbounds ({{.*}} @[[TEMPE]], i32 0, i32 2) + // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1ED1Ev {{.*}} @[[TEMPE]] + // CHECK-COMMON: store {{.*}} @[[TEMPE]], %"struct.MultipleExtension::E"** @_ZN17MultipleExtension2e1E, align 8 E e2 = { A(), B(), D().c }; - // CHECK: call void @_ZN17MultipleExtension1AC1Ev({{.*}} @[[TEMPA:_ZGRN17MultipleExtension2e2E.*]]) - // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1AD1Ev {{.*}} @[[TEMPA]] - // CHECK: store {{.*}} @[[TEMPA]], {{.*}} getelementptr inbounds ({{.*}} @[[E:_ZN17MultipleExtension2e2E]], i32 0, i32 0) + // CHECK-COMMON: call void @_ZN17MultipleExtension1AC1Ev({{.*}} @[[TEMPA:_ZGRN17MultipleExtension2e2E.*]]) + // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1AD1Ev {{.*}} @[[TEMPA]] + // CHECK-COMMON: store {{.*}} @[[TEMPA]], {{.*}} getelementptr inbounds ({{.*}} @[[E:_ZN17MultipleExtension2e2E]], i32 0, i32 0) - // CHECK: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds ({{.*}} @[[E]], i32 0, i32 1)) + // CHECK-COMMON: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds ({{.*}} @[[E]], i32 0, i32 1)) - // CHECK: call void @_ZN17MultipleExtension1DC1Ev({{.*}} @[[TEMPD:_ZGRN17MultipleExtension2e2E.*]]) - // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1DD1Ev {{.*}} @[[TEMPD]] - // CHECK: store {{.*}} @[[TEMPD]], {{.*}} getelementptr inbounds ({{.*}} @[[E]], i32 0, i32 2) - // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1ED1Ev {{.*}} @[[E]] + // CHECK-COMMON: call void @_ZN17MultipleExtension1DC1Ev({{.*}} @[[TEMPD:_ZGRN17MultipleExtension2e2E.*]]) + // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1DD1Ev {{.*}} @[[TEMPD]] + // CHECK-COMMON: store {{.*}} @[[TEMPD]], {{.*}} getelementptr inbounds ({{.*}} @[[E]], i32 0, i32 2) + // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1ED1Ev {{.*}} @[[E]] void g(); - // CHECK: define void @[[NS:_ZN17MultipleExtension]]1fEv( + // CHECK-COMMON: define void @[[NS:_ZN17MultipleExtension]]1fEv( void f() { E &&e1 = { A(), B(), D().c }; - // CHECK: %[[TEMPE1_A:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1:.*]], i32 0, i32 0 - // CHECK: call void @[[NS]]1AC1Ev({{.*}} %[[TEMPA1:.*]]) - // CHECK: store {{.*}} %[[TEMPA1]], {{.*}} %[[TEMPE1_A]] - // CHECK: %[[TEMPE1_B:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i32 0, i32 1 - // CHECK: call void @[[NS]]1BC1Ev({{.*}} %[[TEMPE1_B]]) - // CHECK: %[[TEMPE1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i32 0, i32 2 - // CHECK: call void @[[NS]]1DC1Ev({{.*}} %[[TEMPD1:.*]]) - // CHECK: %[[TEMPD1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD1]], i32 0, i32 1 - // CHECK: store {{.*}} %[[TEMPD1_C]], {{.*}} %[[TEMPE1_C]] - // CHECK: store {{.*}} %[[TEMPE1]], {{.*}} %[[E1:.*]] + // CHECK-COMMON: %[[TEMPE1_A:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1:.*]], i32 0, i32 0 + // CHECK-COMMON: call void @[[NS]]1AC1Ev({{.*}} %[[TEMPA1:.*]]) + // CHECK-COMMON: store {{.*}} %[[TEMPA1]], {{.*}} %[[TEMPE1_A]] + // CHECK-COMMON: %[[TEMPE1_B:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i32 0, i32 1 + // CHECK-COMMON: call void @[[NS]]1BC1Ev({{.*}} %[[TEMPE1_B]]) + // CHECK-COMMON: %[[TEMPE1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i32 0, i32 2 + // CHECK-COMMON: call void @[[NS]]1DC1Ev({{.*}} %[[TEMPD1:.*]]) + // CHECK-COMMON: %[[TEMPD1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD1]], i32 0, i32 1 + // CHECK-COMMON: store {{.*}} %[[TEMPD1_C]], {{.*}} %[[TEMPE1_C]] + // CHECK-COMMON: store {{.*}} %[[TEMPE1]], {{.*}} %[[E1:.*]] g(); - // CHECK: call void @[[NS]]1gEv() + // CHECK-COMMON: call void @[[NS]]1gEv() E e2 = { A(), B(), D().c }; - // CHECK: %[[TEMPE2_A:.*]] = getelementptr inbounds {{.*}} %[[E2:.*]], i32 0, i32 0 - // CHECK: call void @[[NS]]1AC1Ev({{.*}} %[[TEMPA2:.*]]) - // CHECK: store {{.*}} %[[TEMPA2]], {{.*}} %[[TEMPE2_A]] - // CHECK: %[[TEMPE2_B:.*]] = getelementptr inbounds {{.*}} %[[E2]], i32 0, i32 1 - // CHECK: call void @[[NS]]1BC1Ev({{.*}} %[[TEMPE2_B]]) - // CHECK: %[[TEMPE2_C:.*]] = getelementptr inbounds {{.*}} %[[E2]], i32 0, i32 2 - // CHECK: call void @[[NS]]1DC1Ev({{.*}} %[[TEMPD2:.*]]) - // CHECK: %[[TEMPD2_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD2]], i32 0, i32 1 - // CHECK: store {{.*}} %[[TEMPD2_C]], {{.*}}* %[[TEMPE2_C]] + // CHECK-COMMON: %[[TEMPE2_A:.*]] = getelementptr inbounds {{.*}} %[[E2:.*]], i32 0, i32 0 + // CHECK-COMMON: call void @[[NS]]1AC1Ev({{.*}} %[[TEMPA2:.*]]) + // CHECK-COMMON: store {{.*}} %[[TEMPA2]], {{.*}} %[[TEMPE2_A]] + // CHECK-COMMON: %[[TEMPE2_B:.*]] = getelementptr inbounds {{.*}} %[[E2]], i32 0, i32 1 + // CHECK-COMMON: call void @[[NS]]1BC1Ev({{.*}} %[[TEMPE2_B]]) + // CHECK-COMMON: %[[TEMPE2_C:.*]] = getelementptr inbounds {{.*}} %[[E2]], i32 0, i32 2 + // CHECK-COMMON: call void @[[NS]]1DC1Ev({{.*}} %[[TEMPD2:.*]]) + // CHECK-COMMON: %[[TEMPD2_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD2]], i32 0, i32 1 + // CHECK-COMMON: store {{.*}} %[[TEMPD2_C]], {{.*}}* %[[TEMPE2_C]] g(); - // CHECK: call void @[[NS]]1gEv() - - // CHECK: call void @[[NS]]1ED1Ev({{.*}} %[[E2]]) - // CHECK: call void @[[NS]]1DD1Ev({{.*}} %[[TEMPD2]]) - // CHECK: call void @[[NS]]1AD1Ev({{.*}} %[[TEMPA2]]) - // CHECK: call void @[[NS]]1ED1Ev({{.*}} %[[TEMPE1]]) - // CHECK: call void @[[NS]]1DD1Ev({{.*}} %[[TEMPD1]]) - // CHECK: call void @[[NS]]1AD1Ev({{.*}} %[[TEMPA1]]) + // CHECK-COMMON: call void @[[NS]]1gEv() + + // CHECK-COMMON: call void @[[NS]]1ED1Ev({{.*}} %[[E2]]) + // CHECK-COMMON: call void @[[NS]]1DD1Ev({{.*}} %[[TEMPD2]]) + // CHECK-COMMON: call void @[[NS]]1AD1Ev({{.*}} %[[TEMPA2]]) + // CHECK-COMMON: call void @[[NS]]1ED1Ev({{.*}} %[[TEMPE1]]) + // CHECK-COMMON: call void @[[NS]]1DD1Ev({{.*}} %[[TEMPD1]]) + // CHECK-COMMON: call void @[[NS]]1AD1Ev({{.*}} %[[TEMPA1]]) } } @@ -785,27 +787,27 @@ void f() { using T = A[3]; - // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 1 - // CHECK-NOT: @_ZN11ArrayAccess1AD - // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 2 - // CHECK-NOT: @_ZN11ArrayAccess1AD - // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 3 - // CHECK-NOT: @_ZN11ArrayAccess1AD + // CHECK-COMMON: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 1 + // CHECK-COMMON-NOT: @_ZN11ArrayAccess1AD + // CHECK-COMMON: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 2 + // CHECK-COMMON-NOT: @_ZN11ArrayAccess1AD + // CHECK-COMMON: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 3 + // CHECK-COMMON-NOT: @_ZN11ArrayAccess1AD A &&a = T{1, 2, 3}[1]; - // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 4 - // CHECK-NOT: @_ZN11ArrayAccess1AD - // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 5 - // CHECK-NOT: @_ZN11ArrayAccess1AD - // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 6 - // CHECK-NOT: @_ZN11ArrayAccess1AD + // CHECK-COMMON: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 4 + // CHECK-COMMON-NOT: @_ZN11ArrayAccess1AD + // CHECK-COMMON: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 5 + // CHECK-COMMON-NOT: @_ZN11ArrayAccess1AD + // CHECK-COMMON: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 6 + // CHECK-COMMON-NOT: @_ZN11ArrayAccess1AD A &&b = 2[T{4, 5, 6}]; - // CHECK: call void @_ZN11ArrayAccess1gEv( + // CHECK-COMMON: call void @_ZN11ArrayAccess1gEv( g(); - // CHECK: call void @_ZN11ArrayAccess1AD - // CHECK: call void @_ZN11ArrayAccess1AD + // CHECK-COMMON: call void @_ZN11ArrayAccess1AD + // CHECK-COMMON: call void @_ZN11ArrayAccess1AD } } @@ -813,8 +815,8 @@ struct S { S(int); }; struct U { S &&s; }; U v { { 0 } }; - // CHECK: call void @_ZN7PR141301SC1Ei({{.*}} @_ZGRN7PR141301vE_, i32 0) - // CHECK: store {{.*}} @_ZGRN7PR141301vE_, {{.*}} @_ZN7PR141301vE + // CHECK-COMMON: call void @_ZN7PR141301SC1Ei({{.*}} @_ZGRN7PR141301vE_, i32 0) + // CHECK-COMMON: store {{.*}} @_ZGRN7PR141301vE_, {{.*}} @_ZN7PR141301vE } namespace Ctor { @@ -824,8 +826,8 @@ A &&a; B() : a{} { f(); } } b; - // CHECK: define {{.*}}void @_ZN4Ctor1BC1Ev( - // CHECK: call void @_ZN4Ctor1AC1Ev( - // CHECK: call void @_ZN4Ctor1fEv( - // CHECK: call void @_ZN4Ctor1AD1Ev( + // CHECK-COMMON: define {{.*}}void @_ZN4Ctor1BC1Ev( + // CHECK-COMMON: call void @_ZN4Ctor1AC1Ev( + // CHECK-COMMON: call void @_ZN4Ctor1fEv( + // CHECK-COMMON: call void @_ZN4Ctor1AD1Ev( } Index: test/Driver/clang_f_opts.c =================================================================== --- test/Driver/clang_f_opts.c +++ test/Driver/clang_f_opts.c @@ -348,7 +348,6 @@ // RUN: -fwhole-program \ // RUN: -fcaller-saves \ // RUN: -freorder-blocks \ -// RUN: -fdelete-null-pointer-checks \ // RUN: -ffat-lto-objects \ // RUN: -fmerge-constants \ // RUN: -finline-small-functions \ @@ -414,7 +413,6 @@ // CHECK-WARNING-DAG: optimization flag '-fwhole-program' is not supported // CHECK-WARNING-DAG: optimization flag '-fcaller-saves' is not supported // CHECK-WARNING-DAG: optimization flag '-freorder-blocks' is not supported -// CHECK-WARNING-DAG: optimization flag '-fdelete-null-pointer-checks' is not supported // CHECK-WARNING-DAG: optimization flag '-ffat-lto-objects' is not supported // CHECK-WARNING-DAG: optimization flag '-fmerge-constants' is not supported // CHECK-WARNING-DAG: optimization flag '-finline-small-functions' is not supported @@ -526,3 +524,10 @@ // RUN: %clang -### -S -fno-merge-all-constants -fmerge-all-constants %s 2>&1 | FileCheck -check-prefix=CHECK-MERGE-ALL-CONSTANTS %s // CHECK-NO-MERGE-ALL-CONSTANTS-NOT: "-fmerge-all-constants" // CHECK-MERGE-ALL-CONSTANTS: "-fmerge-all-constants" + +// RUN: %clang -### -S -fdelete-null-pointer-checks %s 2>&1 | FileCheck -check-prefix=CHECK-NULL-POINTER-CHECKS %s +// RUN: %clang -### -S -fno-delete-null-pointer-checks %s 2>&1 | FileCheck -check-prefix=CHECK-NO-NULL-POINTER-CHECKS %s +// RUN: %clang -### -S -fdelete-null-pointer-checks -fno-delete-null-pointer-checks %s 2>&1 | FileCheck -check-prefix=CHECK-NO-NULL-POINTER-CHECKS %s +// RUN: %clang -### -S -fno-delete-null-pointer-checks -fdelete-null-pointer-checks %s 2>&1 | FileCheck -check-prefix=CHECK-NULL-POINTER-CHECKS %s +// CHECK-NO-NULL-POINTER-CHECKS: "-fno-delete-null-pointer-checks" +// CHECK-NULL-POINTER-CHECKS-NOT: "-fno-delete-null-pointer-checks" Index: test/Sema/nonnull.c =================================================================== --- test/Sema/nonnull.c +++ test/Sema/nonnull.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -fno-delete-null-pointer-checks -verify %s // rdar://9584012 typedef struct {