> On Oct 13, 2017, at 4:33 PM, Peter Collingbourne <pe...@pcc.me.uk> wrote:
> 
> 
> 
> On Fri, Oct 13, 2017 at 4:19 PM, Vedant Kumar <v...@apple.com 
> <mailto:v...@apple.com>> wrote:
> 
>> On Oct 13, 2017, at 4:08 PM, Peter Collingbourne <pe...@pcc.me.uk 
>> <mailto:pe...@pcc.me.uk>> wrote:
>> 
>> On Fri, Oct 13, 2017 at 4:06 PM, Peter Collingbourne <pe...@pcc.me.uk 
>> <mailto:pe...@pcc.me.uk>> wrote:
>> Here's a small reproducer.
>> 
>> struct A {
>>   virtual void f(...);
>> };
>> 
>> struct B : virtual A {
>>   virtual void b();
>>   virtual void f(...);
>> };
>> 
>> void B::f(...) {}
>> 
>> $ clang++ -fsanitize=function fsan.cpp -ffunction-sections -fdata-sections 
>> -c -o /dev/null
>> fatal error: error in backend: Cannot represent a difference across sections
>> 
>> Looking at the IR I see this function definition:
>> define void @_ZTv0_n24_N1B1fEz(%struct.B* %this, ...) unnamed_addr #0 align 
>> 2 prologue <{ i32, i32 }> <{ i32 846595819, i32 trunc (i64 sub (i64 ptrtoint 
>> (i8** @0 to i64), i64 ptrtoint (void (%struct.B*, ...)* @_ZN1B1fEz to i64)) 
>> to i32) }> {
>> which appears to cause the error.
>> 
>> I get basically the same IR if I use a Darwin target triple, so this isn't a 
>> Linux-specific issue. (On Darwin we end up successfully creating an object 
>> file, but the embedded offset in the text section will presumably be 
>> incorrect.)
>> 
>> Note that we're emitting prologue data on virtual functions, which is 
>> unnecessary because -fsanitize=function only checks indirect calls via 
>> function pointers. So I imagine that one way to solve the problem would be 
>> to turn off prologue data emission on non-virtual functions.
>> 
>> Sorry, I meant "limit prologue data emission to non-virtual functions".
> 
> That's independently a great idea :).
> 
> I don't see a problem in the IR you've showed above, however. Why do you 
> expect the embedded offset to be incorrect? This program links and runs fine 
> on Darwin:
> 
> ---
> struct A {
>   virtual void f(...) {}
> };
> 
> struct B : virtual A {
>   virtual void b() {}
>   virtual void f(...);
> };
> 
> void B::f(...) {}
> 
> int main() {
>   A a;
>   a.f();
> 
>   B b;
>   b.f();
>   b.b();
>   return 0;
> }
> ---
> 
> The "Cannot represent difference..." error appears limited to ELF and Wasm, 
> afaik.
> 
> In order to find the RTTI data for a function, the generated code will add 
> the embedded offset to the function's address in order to find the global 
> that contains the pointer to the RTTI data. So if we were to compute the 
> address of _ZTv0_n24_N1B1fEz's global, we would compute the value:
> _ZTv0_n24_N1B1fEz + (@0 -_ZN1B1fEz)
> which, of course, will not yield the address of @0.
> 
> I would certainly expect your program to run correctly because we do not try 
> to interpret the prologue data when calling a virtual function, so the 
> incorrectness of the offset has no effect on the program's execution.

Thanks for explaining. I am still confused on one point.

Calling a function pointer to a virtual member doesn't seem to trigger a UBSan 
type check. I can see why "_ZTv0_n24_N1B1fEz + (@0 -_ZN1B1fEz)" doesn't make 
sense, but I don't know how we'd ever get there. Consider:

---
class A {
public:
  virtual int f() = 0;
};

class B : public A {
  int f() { return 42; }
};

struct C {
  void g() {}
  static void h() {}
};

int main() {
  auto h = &C::h;
  h(); // type checked

  C c;
  void (C::*g)() = &C::g;
  (c.*g)(); // not checked

  int (A::*f)() = &A::f;
  A *a = new B;
  return (a->*f)(); // not checked
}
---

So, I'm not sure how we would get into a situation where we compute 
"_ZTv0_n24_N1B1fEz + (@0 -_ZN1B1fEz)". In the last code example I posted, there 
are also no calls to the function type check handler.

At any rate, I implemented your idea to not emit signatures for virtual methods:
https://reviews.llvm.org/D38913 <https://reviews.llvm.org/D38913>

It's at least good for a code size savings, and it might fix the issue Eric and 
Han are seeing. I'd appreciate any feedback.

thanks,
vedant


> 
> Peter
> 
> 
> vedant
> 
>> 
>> Peter
>> 
>> On Fri, Oct 13, 2017 at 3:06 PM, Vedant Kumar <v...@apple.com 
>> <mailto:v...@apple.com>> wrote:
>> 
>>> On Oct 13, 2017, at 2:52 PM, Eric Christopher <echri...@gmail.com 
>>> <mailto:echri...@gmail.com>> wrote:
>>> 
>>> 
>>> 
>>> On Fri, Oct 13, 2017 at 2:50 PM Vedant Kumar <v...@apple.com 
>>> <mailto:v...@apple.com>> wrote:
>>>> On Oct 13, 2017, at 1:44 PM, Eric Christopher <echri...@gmail.com 
>>>> <mailto:echri...@gmail.com>> wrote:
>>>> 
>>>> 
>>>> 
>>>> On Fri, Oct 13, 2017 at 1:42 PM Vedant Kumar <v...@apple.com 
>>>> <mailto:v...@apple.com>> wrote:
>>>>> On Oct 13, 2017, at 1:39 PM, Vedant Kumar <v...@apple.com 
>>>>> <mailto:v...@apple.com>> wrote:
>>>>> 
>>>>> Hey Eric,
>>>>> 
>>>>> I'm sorry for the breakage. I made sure to check the run-time tests in 
>>>>> compiler-rt but we could have missing coverage there.
>>>>> 
>>>>> The original version of this patch restricted the prologue data changes 
>>>>> to Darwin only. We can switch back to that easily, just let me know.
>>>> 
>>>> Actually I'll go ahead and work a patch up.
>>>> 
>>>> 
>>>> Appreciated :)
>>>> 
>>>> Basically we were getting an error of:
>>>> 
>>>> error: Cannot represent a difference across sections
>>>> 
>>>> trying to compile things with the current code.
>>> 
>>> Oh I see.. well, we started using a difference between the address of a 
>>> function and the address of a global, so the error makes sense.
>>> 
>>> I'd be interested in any factors that could narrow the problem down (e.g 
>>> using a specific linker, using -ffunction-sections, using data-sections, 
>>> etc). Basically I'm not sure why this would work on some Linux setups but 
>>> not others.
>>> 
>>> 
>>> Definitely using the latter two options and gold as a linker. I'll see what 
>>> Han can come up with.
>> 
>> Gotcha. Well, -ffunction-sections appears to be untested in 
>> compiler-rt/test/ubsan, at least.
>> 
>> There's a test somewhere in there called function.cpp -- it would be great 
>> if we could cover the *-sections options there. I'm not sure whether that's 
>> what caused the failure, but the extra coverage couldn't hurt :). I would do 
>> it myself but I don't have a Linux machine to test on.
>> 
>> vedant
>> 
>>>  
>>> While we figure that out here's a patch to limit the impact on non-Darwin 
>>> platforms:
>>> https://reviews.llvm.org/D38903 <https://reviews.llvm.org/D38903>
>>> 
>>> *goes a looking*
>>> 
>>> Thanks!
>>> 
>>> -eric 
>>> 
>>> vedant
>>> 
>>>> 
>>>> Thanks!
>>>> 
>>>> -eric
>>>>  
>>>> vedant
>>>> 
>>>>> 
>>>>> vedant
>>>>> 
>>>>> 
>>>>>> On Oct 13, 2017, at 1:33 PM, Eric Christopher <echri...@gmail.com 
>>>>>> <mailto:echri...@gmail.com>> wrote:
>>>>>> 
>>>>>> Hi Vedant,
>>>>>> 
>>>>>> So this actually broke -fsanitize=function on linux. Han is working up a 
>>>>>> testcase for it, but letting you know for now that we'll probably need 
>>>>>> some change here.
>>>>>> 
>>>>>> -eric
>>>>>> 
>>>>>> On Tue, Sep 12, 2017 at 5:05 PM Vedant Kumar via cfe-commits 
>>>>>> <cfe-commits@lists.llvm.org <mailto:cfe-commits@lists.llvm.org>> wrote:
>>>>>> Author: vedantk
>>>>>> Date: Tue Sep 12 17:04:35 2017
>>>>>> New Revision: 313096
>>>>>> 
>>>>>> URL: http://llvm.org/viewvc/llvm-project?rev=313096&view=rev 
>>>>>> <http://llvm.org/viewvc/llvm-project?rev=313096&view=rev>
>>>>>> Log:
>>>>>> [ubsan] Function Sanitizer: Don't require writable text segments
>>>>>> 
>>>>>> This change will make it possible to use -fsanitize=function on Darwin 
>>>>>> and
>>>>>> possibly on other platforms. It fixes an issue with the way RTTI is 
>>>>>> stored into
>>>>>> function prologue data.
>>>>>> 
>>>>>> On Darwin, addresses stored in prologue data can't require run-time 
>>>>>> fixups and
>>>>>> must be PC-relative. Run-time fixups are undesirable because they 
>>>>>> necessitate
>>>>>> writable text segments, which can lead to security issues. And absolute
>>>>>> addresses are undesirable because they break PIE mode.
>>>>>> 
>>>>>> The fix is to create a private global which points to the RTTI, and then 
>>>>>> to
>>>>>> encode a PC-relative reference to the global into prologue data.
>>>>>> 
>>>>>> Differential Revision: https://reviews.llvm.org/D37597 
>>>>>> <https://reviews.llvm.org/D37597>
>>>>>> 
>>>>>> Modified:
>>>>>>     cfe/trunk/lib/CodeGen/CGExpr.cpp
>>>>>>     cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
>>>>>>     cfe/trunk/lib/CodeGen/CodeGenFunction.h
>>>>>>     cfe/trunk/lib/CodeGen/TargetInfo.cpp
>>>>>>     cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp
>>>>>> 
>>>>>> Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
>>>>>> URL: 
>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=313096&r1=313095&r2=313096&view=diff
>>>>>>  
>>>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=313096&r1=313095&r2=313096&view=diff>
>>>>>> ==============================================================================
>>>>>> --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
>>>>>> +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Sep 12 17:04:35 2017
>>>>>> @@ -4409,10 +4409,7 @@ RValue CodeGenFunction::EmitCall(QualTyp
>>>>>>        SanitizerScope SanScope(this);
>>>>>>        llvm::Constant *FTRTTIConst =
>>>>>>            CGM.GetAddrOfRTTIDescriptor(QualType(FnType, 0), 
>>>>>> /*ForEH=*/true);
>>>>>> -      llvm::Type *PrefixStructTyElems[] = {
>>>>>> -        PrefixSig->getType(),
>>>>>> -        FTRTTIConst->getType()
>>>>>> -      };
>>>>>> +      llvm::Type *PrefixStructTyElems[] = {PrefixSig->getType(), 
>>>>>> Int32Ty};
>>>>>>        llvm::StructType *PrefixStructTy = llvm::StructType::get(
>>>>>>            CGM.getLLVMContext(), PrefixStructTyElems, /*isPacked=*/true);
>>>>>> 
>>>>>> @@ -4433,8 +4430,10 @@ RValue CodeGenFunction::EmitCall(QualTyp
>>>>>>        EmitBlock(TypeCheck);
>>>>>>        llvm::Value *CalleeRTTIPtr =
>>>>>>            Builder.CreateConstGEP2_32(PrefixStructTy, 
>>>>>> CalleePrefixStruct, 0, 1);
>>>>>> -      llvm::Value *CalleeRTTI =
>>>>>> +      llvm::Value *CalleeRTTIEncoded =
>>>>>>            Builder.CreateAlignedLoad(CalleeRTTIPtr, getPointerAlign());
>>>>>> +      llvm::Value *CalleeRTTI =
>>>>>> +          DecodeAddrUsedInPrologue(CalleePtr, CalleeRTTIEncoded);
>>>>>>        llvm::Value *CalleeRTTIMatch =
>>>>>>            Builder.CreateICmpEQ(CalleeRTTI, FTRTTIConst);
>>>>>>        llvm::Constant *StaticData[] = {
>>>>>> 
>>>>>> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
>>>>>> URL: 
>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=313096&r1=313095&r2=313096&view=diff
>>>>>>  
>>>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=313096&r1=313095&r2=313096&view=diff>
>>>>>> ==============================================================================
>>>>>> --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
>>>>>> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Tue Sep 12 17:04:35 2017
>>>>>> @@ -429,6 +429,43 @@ bool CodeGenFunction::ShouldXRayInstrume
>>>>>>    return CGM.getCodeGenOpts().XRayInstrumentFunctions;
>>>>>>  }
>>>>>> 
>>>>>> +llvm::Constant *
>>>>>> +CodeGenFunction::EncodeAddrForUseInPrologue(llvm::Function *F,
>>>>>> +                                            llvm::Constant *Addr) {
>>>>>> +  // Addresses stored in prologue data can't require run-time fixups 
>>>>>> and must
>>>>>> +  // be PC-relative. Run-time fixups are undesirable because they 
>>>>>> necessitate
>>>>>> +  // writable text segments, which are unsafe. And absolute addresses 
>>>>>> are
>>>>>> +  // undesirable because they break PIE mode.
>>>>>> +
>>>>>> +  // Add a layer of indirection through a private global. Taking its 
>>>>>> address
>>>>>> +  // won't result in a run-time fixup, even if Addr has linkonce_odr 
>>>>>> linkage.
>>>>>> +  auto *GV = new llvm::GlobalVariable(CGM.getModule(), Addr->getType(),
>>>>>> +                                      /*isConstant=*/true,
>>>>>> +                                      
>>>>>> llvm::GlobalValue::PrivateLinkage, Addr);
>>>>>> +
>>>>>> +  // Create a PC-relative address.
>>>>>> +  auto *GOTAsInt = llvm::ConstantExpr::getPtrToInt(GV, IntPtrTy);
>>>>>> +  auto *FuncAsInt = llvm::ConstantExpr::getPtrToInt(F, IntPtrTy);
>>>>>> +  auto *PCRelAsInt = llvm::ConstantExpr::getSub(GOTAsInt, FuncAsInt);
>>>>>> +  return (IntPtrTy == Int32Ty)
>>>>>> +             ? PCRelAsInt
>>>>>> +             : llvm::ConstantExpr::getTrunc(PCRelAsInt, Int32Ty);
>>>>>> +}
>>>>>> +
>>>>>> +llvm::Value *
>>>>>> +CodeGenFunction::DecodeAddrUsedInPrologue(llvm::Value *F,
>>>>>> +                                          llvm::Value *EncodedAddr) {
>>>>>> +  // Reconstruct the address of the global.
>>>>>> +  auto *PCRelAsInt = Builder.CreateSExt(EncodedAddr, IntPtrTy);
>>>>>> +  auto *FuncAsInt = Builder.CreatePtrToInt(F, IntPtrTy, "func_addr.int 
>>>>>> <http://func_addr.int/>");
>>>>>> +  auto *GOTAsInt = Builder.CreateAdd(PCRelAsInt, FuncAsInt, 
>>>>>> "global_addr.int <http://global_addr.int/>");
>>>>>> +  auto *GOTAddr = Builder.CreateIntToPtr(GOTAsInt, Int8PtrPtrTy, 
>>>>>> "global_addr");
>>>>>> +
>>>>>> +  // Load the original pointer through the global.
>>>>>> +  return Builder.CreateLoad(Address(GOTAddr, getPointerAlign()),
>>>>>> +                            "decoded_addr");
>>>>>> +}
>>>>>> +
>>>>>>  /// EmitFunctionInstrumentation - Emit LLVM code to call the specified
>>>>>>  /// instrumentation function with the current function and the call 
>>>>>> site, if
>>>>>>  /// function instrumentation is enabled.
>>>>>> @@ -856,7 +893,10 @@ void CodeGenFunction::StartFunction(Glob
>>>>>>                
>>>>>> CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) {
>>>>>>          llvm::Constant *FTRTTIConst =
>>>>>>              CGM.GetAddrOfRTTIDescriptor(FD->getType(), /*ForEH=*/true);
>>>>>> -        llvm::Constant *PrologueStructElems[] = { PrologueSig, 
>>>>>> FTRTTIConst };
>>>>>> +        llvm::Constant *FTRTTIConstEncoded =
>>>>>> +            EncodeAddrForUseInPrologue(Fn, FTRTTIConst);
>>>>>> +        llvm::Constant *PrologueStructElems[] = {PrologueSig,
>>>>>> +                                                 FTRTTIConstEncoded};
>>>>>>          llvm::Constant *PrologueStructConst =
>>>>>>              llvm::ConstantStruct::getAnon(PrologueStructElems, 
>>>>>> /*Packed=*/true);
>>>>>>          Fn->setPrologueData(PrologueStructConst);
>>>>>> 
>>>>>> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
>>>>>> URL: 
>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=313096&r1=313095&r2=313096&view=diff
>>>>>>  
>>>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=313096&r1=313095&r2=313096&view=diff>
>>>>>> ==============================================================================
>>>>>> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
>>>>>> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Sep 12 17:04:35 2017
>>>>>> @@ -1776,6 +1776,15 @@ public:
>>>>>>    /// EmitMCountInstrumentation - Emit call to .mcount.
>>>>>>    void EmitMCountInstrumentation();
>>>>>> 
>>>>>> +  /// Encode an address into a form suitable for use in a function 
>>>>>> prologue.
>>>>>> +  llvm::Constant *EncodeAddrForUseInPrologue(llvm::Function *F,
>>>>>> +                                             llvm::Constant *Addr);
>>>>>> +
>>>>>> +  /// Decode an address used in a function prologue, encoded by \c
>>>>>> +  /// EncodeAddrForUseInPrologue.
>>>>>> +  llvm::Value *DecodeAddrUsedInPrologue(llvm::Value *F,
>>>>>> +                                        llvm::Value *EncodedAddr);
>>>>>> +
>>>>>>    /// EmitFunctionProlog - Emit the target specific LLVM code to load 
>>>>>> the
>>>>>>    /// arguments for the given function. This is also responsible for 
>>>>>> naming the
>>>>>>    /// LLVM function arguments.
>>>>>> 
>>>>>> Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
>>>>>> URL: 
>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=313096&r1=313095&r2=313096&view=diff
>>>>>>  
>>>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=313096&r1=313095&r2=313096&view=diff>
>>>>>> ==============================================================================
>>>>>> --- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
>>>>>> +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Tue Sep 12 17:04:35 2017
>>>>>> @@ -1086,8 +1086,8 @@ public:
>>>>>>    getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override 
>>>>>> {
>>>>>>      unsigned Sig = (0xeb << 0) |  // jmp rel8
>>>>>>                     (0x06 << 8) |  //           .+0x08
>>>>>> -                   ('F' << 16) |
>>>>>> -                   ('T' << 24);
>>>>>> +                   ('v' << 16) |
>>>>>> +                   ('2' << 24);
>>>>>>      return llvm::ConstantInt::get(CGM.Int32Ty, Sig);
>>>>>>    }
>>>>>> 
>>>>>> @@ -2277,17 +2277,10 @@ public:
>>>>>> 
>>>>>>    llvm::Constant *
>>>>>>    getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override 
>>>>>> {
>>>>>> -    unsigned Sig;
>>>>>> -    if (getABIInfo().has64BitPointers())
>>>>>> -      Sig = (0xeb << 0) |  // jmp rel8
>>>>>> -            (0x0a << 8) |  //           .+0x0c
>>>>>> -            ('F' << 16) |
>>>>>> -            ('T' << 24);
>>>>>> -    else
>>>>>> -      Sig = (0xeb << 0) |  // jmp rel8
>>>>>> -            (0x06 << 8) |  //           .+0x08
>>>>>> -            ('F' << 16) |
>>>>>> -            ('T' << 24);
>>>>>> +    unsigned Sig = (0xeb << 0) | // jmp rel8
>>>>>> +                   (0x06 << 8) | //           .+0x08
>>>>>> +                   ('v' << 16) |
>>>>>> +                   ('2' << 24);
>>>>>>      return llvm::ConstantInt::get(CGM.Int32Ty, Sig);
>>>>>>    }
>>>>>> 
>>>>>> 
>>>>>> Modified: cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp
>>>>>> URL: 
>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp?rev=313096&r1=313095&r2=313096&view=diff
>>>>>>  
>>>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp?rev=313096&r1=313095&r2=313096&view=diff>
>>>>>> ==============================================================================
>>>>>> --- cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp (original)
>>>>>> +++ cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp Tue Sep 12 
>>>>>> 17:04:35 2017
>>>>>> @@ -16,6 +16,10 @@ struct S {
>>>>>>  // Check that type mismatch handler is not modified by ASan.
>>>>>>  // CHECK-ASAN: private unnamed_addr global { { [{{.*}} x i8]*, i32, i32 
>>>>>> }, { i16, i16, [4 x i8] }*, i8*, i8 } { {{.*}}, { i16, i16, [4 x i8] }* 
>>>>>> [[TYPE_DESCR]], {{.*}} }
>>>>>> 
>>>>>> +// CHECK: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* 
>>>>>> bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*)
>>>>>> +// CHECK-X86: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* 
>>>>>> bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*)
>>>>>> +// CHECK-X32: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* 
>>>>>> bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*)
>>>>>> +
>>>>>>  struct T : S {};
>>>>>> 
>>>>>>  // CHECK-LABEL: @_Z17reference_binding
>>>>>> @@ -395,23 +399,30 @@ void downcast_reference(B &b) {
>>>>>>    // CHECK-NEXT: br i1 [[AND]]
>>>>>>  }
>>>>>> 
>>>>>> -// CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prologue <{ 
>>>>>> i32, i8* }> <{ i32 1413876459, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE 
>>>>>> to i8*) }>
>>>>>> -// CHECK-X32: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, 
>>>>>> i8* }> <{ i32 1413875435, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to 
>>>>>> i8*) }>
>>>>>> -// CHECK-X86: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, 
>>>>>> i8* }> <{ i32 1413875435, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to 
>>>>>> i8*) }>
>>>>>> +//
>>>>>> +// CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prologue <{ 
>>>>>> i32, i32 }> <{ i32 846595819, i32 trunc (i64 sub (i64 ptrtoint (i8** 
>>>>>> {{.*}} to i64), i64 ptrtoint (void (void (i32)*)* 
>>>>>> @_Z22indirect_function_callPFviE to i64)) to i32) }>
>>>>>> +// CHECK-X32: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, 
>>>>>> i32 }> <{ i32 846595819, i32 sub (i32 ptrtoint (i8** 
>>>>>> [[IndirectRTTI_ZTIFvPFviEE]] to i32), i32 ptrtoint (void (void (i32)*)* 
>>>>>> @_Z22indirect_function_callPFviE to i32)) }>
>>>>>> +// CHECK-X86: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, 
>>>>>> i32 }> <{ i32 846595819, i32 sub (i32 ptrtoint (i8** 
>>>>>> [[IndirectRTTI_ZTIFvPFviEE]] to i32), i32 ptrtoint (void (void (i32)*)* 
>>>>>> @_Z22indirect_function_callPFviE to i32)) }>
>>>>>>  void indirect_function_call(void (*p)(int)) {
>>>>>> -  // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i8* }>*
>>>>>> +  // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i32 }>*
>>>>>> 
>>>>>>    // Signature check
>>>>>> -  // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i8* }>, <{ i32, 
>>>>>> i8* }>* [[PTR]], i32 0, i32 0
>>>>>> +  // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, 
>>>>>> i32 }>* [[PTR]], i32 0, i32 0
>>>>>>    // CHECK-NEXT: [[SIG:%.+]] = load i32, i32* [[SIGPTR]]
>>>>>> -  // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 1413876459
>>>>>> +  // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 846595819
>>>>>>    // CHECK-NEXT: br i1 [[SIGCMP]]
>>>>>> 
>>>>>>    // RTTI pointer check
>>>>>> -  // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i8* }>, <{ i32, i8* 
>>>>>> }>* [[PTR]], i32 0, i32 1
>>>>>> -  // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[RTTIPTR]]
>>>>>> +  // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 
>>>>>> }>* [[PTR]], i32 0, i32 1
>>>>>> +  // CHECK-NEXT: [[RTTIEncIntTrunc:%.+]] = load i32, i32* [[RTTIPTR]]
>>>>>> +  // CHECK-NEXT: [[RTTIEncInt:%.+]] = sext i32 [[RTTIEncIntTrunc]] to 
>>>>>> i64
>>>>>> +  // CHECK-NEXT: [[FuncAddrInt:%.+]] = ptrtoint void (i32)* {{.*}} to 
>>>>>> i64
>>>>>> +  // CHECK-NEXT: [[IndirectGVInt:%.+]] = add i64 [[RTTIEncInt]], 
>>>>>> [[FuncAddrInt]]
>>>>>> +  // CHECK-NEXT: [[IndirectGV:%.+]] = inttoptr i64 [[IndirectGVInt]] to 
>>>>>> i8**
>>>>>> +  // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[IndirectGV]], align 8
>>>>>>    // CHECK-NEXT: [[RTTICMP:%.+]] = icmp eq i8* [[RTTI]], bitcast ({ 
>>>>>> i8*, i8* }* @_ZTIFviE to i8*)
>>>>>>    // CHECK-NEXT: br i1 [[RTTICMP]]
>>>>>> +
>>>>>>    p(42);
>>>>>>  }
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> _______________________________________________
>>>>>> cfe-commits mailing list
>>>>>> cfe-commits@lists.llvm.org <mailto:cfe-commits@lists.llvm.org>
>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits 
>>>>>> <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits>
>> 
>> 
>> 
>> -- 
>> -- 
>> Peter
>> 
>> 
>> 
>> -- 
>> -- 
>> Peter
> 
> 
> 
> 
> -- 
> -- 
> Peter

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to