<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jul 31, 2017, at 12:30 PM, Nico Weber <<a href="mailto:thakis@chromium.org" class="">thakis@chromium.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote">On Mon, Jul 31, 2017 at 1:18 PM, Vedant Kumar <span dir="ltr" class=""><<a href="mailto:vsk@apple.com" target="_blank" class="">vsk@apple.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The bot should start working again with -fsanitize=vptr,null.<br class="">
<br class="">
The warning can be improved. If we find -fno-sanitize=null in the argument list, we might say:<br class="">
implicitly disabling vptr sanitizer because "-fno-sanitize=null" was specified<br class="">
<br class="">
Otherwise we might say:<br class="">
implicitly disabling vptr sanitizer because null checking wasn't enabled, try specifying -fsanitize=null or -fsanitize=undefined<br class=""></blockquote><div class=""><br class=""></div><div class="">Hm, I still don't understand. I enable vptr ubsan checking, and I don't want null checking (because chromium happens to be vptr clean and we want to keep it that way, but we're not nullptr clean due to for example v8's SMIs). How do I get yesterday's behavior back?</div></div></div></div></div></blockquote><div><br class=""></div><div>We can teach the -fsanitize=vptr to emit its own null check when -fsanitize=null isn't available (I'll send a patch out for this). I opted not to do this initially to because I expected the two checks to either always be enabled together, or to be mutually compatible.</div><div><br class=""></div><div>vedant</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br class="">
I'll send out a patch for review.<br class="">
<span class="HOEnZb"><font color="#888888" class=""><br class="">
vedant<br class="">
</font></span><div class="HOEnZb"><div class="h5"><br class="">
> On Jul 31, 2017, at 9:37 AM, Hans Wennborg <<a href="mailto:hans@chromium.org" class="">hans@chromium.org</a>> wrote:<br class="">
><br class="">
> /sub<br class="">
><br class="">
> I believe Vedant asked for this to be merged to 5.0, so I'd like to<br class="">
> merge the resolution too.<br class="">
><br class="">
> On Mon, Jul 31, 2017 at 8:51 AM, Nico Weber via cfe-commits<br class="">
> <<a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a>> wrote:<br class="">
>> Hi Vedant,<br class="">
>><br class="">
>> after this change our ubsanvptr bot fails like so:<br class="">
>><br class="">
>> clang-6.0: error: implicitly disabling vptr sanitizer because null checking<br class="">
>> wasn't enabled [-Werror,-Wauto-disable-vptr-<wbr class="">sanitizer]<br class="">
>><br class="">
>> The bot uses -fsanitize=vptr. I have no idea what this warning is supposed<br class="">
>> to tell me. Maybe it could be reworded, or maybe it shouldn't be emitted?<br class="">
>><br class="">
>> Thanks,<br class="">
>> Nico<br class="">
>><br class="">
>> On Tue, Jul 25, 2017 at 3:34 PM, Vedant Kumar via cfe-commits<br class="">
>> <<a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a>> wrote:<br class="">
>>><br class="">
>>> Author: vedantk<br class="">
>>> Date: Tue Jul 25 12:34:23 2017<br class="">
>>> New Revision: 309007<br class="">
>>><br class="">
>>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=309007&view=rev" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project?rev=309007&view=rev</a><br class="">
>>> Log:<br class="">
>>> [ubsan] Null-check pointers in -fsanitize=vptr (PR33881)<br class="">
>>><br class="">
>>> The instrumentation generated by -fsanitize=vptr does not null check a<br class="">
>>> user pointer before loading from it. This causes crashes in the face of<br class="">
>>> UB member calls (this=nullptr), i.e it's causing user programs to crash<br class="">
>>> only after UBSan is turned on.<br class="">
>>><br class="">
>>> The fix is to make run-time null checking a prerequisite for enabling<br class="">
>>> -fsanitize=vptr, and to then teach UBSan to reuse these run-time null<br class="">
>>> checks to make -fsanitize=vptr safe.<br class="">
>>><br class="">
>>> Testing: check-clang, check-ubsan, a stage2 ubsan-enabled build<br class="">
>>><br class="">
>>> Differential Revision: <a href="https://reviews.llvm.org/D35735" rel="noreferrer" target="_blank" class="">https://reviews.llvm.org/<wbr class="">D35735</a><br class="">
>>><br class="">
>>> <a href="https://bugs.llvm.org/show_bug.cgi?id=33881" rel="noreferrer" target="_blank" class="">https://bugs.llvm.org/show_<wbr class="">bug.cgi?id=33881</a><br class="">
>>><br class="">
>>> Modified:<br class="">
>>>    cfe/trunk/docs/ReleaseNotes.<wbr class="">rst<br class="">
>>>    cfe/trunk/docs/<wbr class="">UndefinedBehaviorSanitizer.rst<br class="">
>>>    cfe/trunk/include/clang/Basic/<wbr class="">DiagnosticDriverKinds.td<br class="">
>>>    cfe/trunk/include/clang/Basic/<wbr class="">DiagnosticGroups.td<br class="">
>>>    cfe/trunk/lib/CodeGen/CGExpr.<wbr class="">cpp<br class="">
>>>    cfe/trunk/lib/Driver/<wbr class="">SanitizerArgs.cpp<br class="">
>>>    cfe/trunk/test/CodeGenCXX/<wbr class="">catch-undef-behavior.cpp<br class="">
>>>    cfe/trunk/test/CodeGenCXX/<wbr class="">ubsan-devirtualized-calls.cpp<br class="">
>>>    cfe/trunk/test/CodeGenCXX/<wbr class="">ubsan-type-checks.cpp<br class="">
>>>    cfe/trunk/test/CodeGenCXX/<wbr class="">ubsan-vtable-checks.cpp<br class="">
>>>    cfe/trunk/test/Driver/<wbr class="">fsanitize.c<br class="">
>>>    cfe/trunk/test/Driver/rtti-<wbr class="">options.cpp<br class="">
>>><br class="">
>>> Modified: cfe/trunk/docs/ReleaseNotes.<wbr class="">rst<br class="">
>>> URL:<br class="">
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ReleaseNotes.rst?rev=309007&r1=309006&r2=309007&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/docs/<wbr class="">ReleaseNotes.rst?rev=309007&<wbr class="">r1=309006&r2=309007&view=diff</a><br class="">
>>><br class="">
>>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>>> --- cfe/trunk/docs/ReleaseNotes.<wbr class="">rst (original)<br class="">
>>> +++ cfe/trunk/docs/ReleaseNotes.<wbr class="">rst Tue Jul 25 12:34:23 2017<br class="">
>>> @@ -155,7 +155,9 @@ Static Analyzer<br class="">
>>> Undefined Behavior Sanitizer (UBSan)<br class="">
>>> ------------------------------<wbr class="">------<br class="">
>>><br class="">
>>> -...<br class="">
>>> +The C++ dynamic type check now requires run-time null checking (i.e,<br class="">
>>> +`-fsanitize=vptr` cannot be used without `-fsanitize=null`). This change<br class="">
>>> does<br class="">
>>> +not impact users who rely on UBSan check groups (e.g<br class="">
>>> `-fsanitize=undefined`).<br class="">
>>><br class="">
>>> Core Analysis Improvements<br class="">
>>> ==========================<br class="">
>>><br class="">
>>> Modified: cfe/trunk/docs/<wbr class="">UndefinedBehaviorSanitizer.rst<br class="">
>>> URL:<br class="">
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UndefinedBehaviorSanitizer.rst?rev=309007&r1=309006&r2=309007&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/docs/<wbr class="">UndefinedBehaviorSanitizer.<wbr class="">rst?rev=309007&r1=309006&r2=<wbr class="">309007&view=diff</a><br class="">
>>><br class="">
>>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>>> --- cfe/trunk/docs/<wbr class="">UndefinedBehaviorSanitizer.rst (original)<br class="">
>>> +++ cfe/trunk/docs/<wbr class="">UndefinedBehaviorSanitizer.rst Tue Jul 25 12:34:23 2017<br class="">
>>> @@ -130,11 +130,11 @@ Available checks are:<br class="">
>>>      it is often unintentional, so UBSan offers to catch it.<br class="">
>>>   -  ``-fsanitize=vla-bound``: A variable-length array whose bound<br class="">
>>>      does not evaluate to a positive value.<br class="">
>>> -  -  ``-fsanitize=vptr``: Use of an object whose vptr indicates that<br class="">
>>> -     it is of the wrong dynamic type, or that its lifetime has not<br class="">
>>> -     begun or has ended. Incompatible with ``-fno-rtti``. Link must<br class="">
>>> -     be performed by ``clang++``, not ``clang``, to make sure<br class="">
>>> C++-specific<br class="">
>>> -     parts of the runtime library and C++ standard libraries are present.<br class="">
>>> +  -  ``-fsanitize=vptr``: Use of an object whose vptr indicates that it<br class="">
>>> is of<br class="">
>>> +     the wrong dynamic type, or that its lifetime has not begun or has<br class="">
>>> ended.<br class="">
>>> +     Incompatible with ``-fno-rtti`` and ``-fno-sanitize=null``. Link<br class="">
>>> must be<br class="">
>>> +     performed by ``clang++``, not ``clang``, to make sure C++-specific<br class="">
>>> parts of<br class="">
>>> +     the runtime library and C++ standard libraries are present.<br class="">
>>><br class="">
>>> You can also use the following check groups:<br class="">
>>>   -  ``-fsanitize=undefined``: All of the checks listed above other than<br class="">
>>><br class="">
>>> Modified: cfe/trunk/include/clang/Basic/<wbr class="">DiagnosticDriverKinds.td<br class="">
>>> URL:<br class="">
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td?rev=309007&r1=309006&r2=309007&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/include/<wbr class="">clang/Basic/<wbr class="">DiagnosticDriverKinds.td?rev=<wbr class="">309007&r1=309006&r2=309007&<wbr class="">view=diff</a><br class="">
>>><br class="">
>>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>>> --- cfe/trunk/include/clang/Basic/<wbr class="">DiagnosticDriverKinds.td (original)<br class="">
>>> +++ cfe/trunk/include/clang/Basic/<wbr class="">DiagnosticDriverKinds.td Tue Jul 25<br class="">
>>> 12:34:23 2017<br class="">
>>> @@ -230,7 +230,10 @@ def warn_drv_enabling_rtti_with_<wbr class="">exceptio<br class="">
>>>   InGroup<DiagGroup<"rtti-for-<wbr class="">exceptions">>;<br class="">
>>> def warn_drv_disabling_vptr_no_<wbr class="">rtti_default : Warning<<br class="">
>>>   "implicitly disabling vptr sanitizer because rtti wasn't enabled">,<br class="">
>>> -  InGroup<DiagGroup<"auto-<wbr class="">disable-vptr-sanitizer">>;<br class="">
>>> +  InGroup<<wbr class="">AutoDisableVptrSanitizer>;<br class="">
>>> +def warn_drv_disabling_vptr_no_<wbr class="">null_check : Warning<<br class="">
>>> +  "implicitly disabling vptr sanitizer because null checking wasn't<br class="">
>>> enabled">,<br class="">
>>> +  InGroup<<wbr class="">AutoDisableVptrSanitizer>;<br class="">
>>> def warn_drv_object_size_disabled_<wbr class="">O0 : Warning<<br class="">
>>>   "the object size sanitizer has no effect at -O0, but is explicitly<br class="">
>>> enabled: %0">,<br class="">
>>>   InGroup<<wbr class="">InvalidCommandLineArgument>;<br class="">
>>><br class="">
>>> Modified: cfe/trunk/include/clang/Basic/<wbr class="">DiagnosticGroups.td<br class="">
>>> URL:<br class="">
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=309007&r1=309006&r2=309007&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/include/<wbr class="">clang/Basic/DiagnosticGroups.<wbr class="">td?rev=309007&r1=309006&r2=<wbr class="">309007&view=diff</a><br class="">
>>><br class="">
>>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>>> --- cfe/trunk/include/clang/Basic/<wbr class="">DiagnosticGroups.td (original)<br class="">
>>> +++ cfe/trunk/include/clang/Basic/<wbr class="">DiagnosticGroups.td Tue Jul 25 12:34:23<br class="">
>>> 2017<br class="">
>>> @@ -27,6 +27,7 @@ def GNUAnonymousStruct : DiagGroup<"gnu-<br class="">
>>> def GNUAutoType : DiagGroup<"gnu-auto-type">;<br class="">
>>> def ArrayBounds : DiagGroup<"array-bounds">;<br class="">
>>> def ArrayBoundsPointerArithmetic :<br class="">
>>> DiagGroup<"array-bounds-<wbr class="">pointer-arithmetic">;<br class="">
>>> +def AutoDisableVptrSanitizer : DiagGroup<"auto-disable-vptr-<wbr class="">sanitizer">;<br class="">
>>> def Availability : DiagGroup<"availability">;<br class="">
>>> def Section : DiagGroup<"section">;<br class="">
>>> def AutoImport : DiagGroup<"auto-import">;<br class="">
>>><br class="">
>>> Modified: cfe/trunk/lib/CodeGen/CGExpr.<wbr class="">cpp<br class="">
>>> URL:<br class="">
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=309007&r1=309006&r2=309007&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/CodeGen/<wbr class="">CGExpr.cpp?rev=309007&r1=<wbr class="">309006&r2=309007&view=diff</a><br class="">
>>><br class="">
>>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>>> --- cfe/trunk/lib/CodeGen/CGExpr.<wbr class="">cpp (original)<br class="">
>>> +++ cfe/trunk/lib/CodeGen/CGExpr.<wbr class="">cpp Tue Jul 25 12:34:23 2017<br class="">
>>> @@ -604,20 +604,23 @@ void CodeGenFunction::<wbr class="">EmitTypeCheck(Type<br class="">
>>>   auto PtrToAlloca =<br class="">
>>><br class="">
>>> dyn_cast<llvm::AllocaInst>(<wbr class="">Ptr-><wbr class="">stripPointerCastsNoFollowAlias<wbr class="">es());<br class="">
>>><br class="">
>>> +  llvm::Value *IsNonNull = nullptr;<br class="">
>>> +  bool IsGuaranteedNonNull =<br class="">
>>> +      SkippedChecks.has(<wbr class="">SanitizerKind::Null) || PtrToAlloca;<br class="">
>>>   bool AllowNullPointers = TCK == TCK_DowncastPointer || TCK ==<br class="">
>>> TCK_Upcast ||<br class="">
>>>                            TCK == TCK_UpcastToVirtualBase;<br class="">
>>>   if ((SanOpts.has(SanitizerKind::<wbr class="">Null) || AllowNullPointers) &&<br class="">
>>> -      !SkippedChecks.has(<wbr class="">SanitizerKind::Null) && !PtrToAlloca) {<br class="">
>>> +      !IsGuaranteedNonNull) {<br class="">
>>>     // The glvalue must not be an empty glvalue.<br class="">
>>> -    llvm::Value *IsNonNull = Builder.CreateIsNotNull(Ptr);<br class="">
>>> +    IsNonNull = Builder.CreateIsNotNull(Ptr);<br class="">
>>><br class="">
>>>     // The IR builder can constant-fold the null check if the pointer<br class="">
>>> points to<br class="">
>>>     // a constant.<br class="">
>>> -    bool PtrIsNonNull =<br class="">
>>> +    IsGuaranteedNonNull =<br class="">
>>>         IsNonNull == llvm::ConstantInt::getTrue(<wbr class="">getLLVMContext());<br class="">
>>><br class="">
>>>     // Skip the null check if the pointer is known to be non-null.<br class="">
>>> -    if (!PtrIsNonNull) {<br class="">
>>> +    if (!IsGuaranteedNonNull) {<br class="">
>>>       if (AllowNullPointers) {<br class="">
>>>         // When performing pointer casts, it's OK if the value is null.<br class="">
>>>         // Skip the remaining checks in that case.<br class="">
>>> @@ -691,12 +694,24 @@ void CodeGenFunction::<wbr class="">EmitTypeCheck(Type<br class="">
>>>   //    -- the [pointer or glvalue] is used to access a non-static data<br class="">
>>> member<br class="">
>>>   //       or call a non-static member function<br class="">
>>>   CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();<br class="">
>>> +  bool HasNullCheck = IsGuaranteedNonNull || IsNonNull;<br class="">
>>>   if (SanOpts.has(SanitizerKind::<wbr class="">Vptr) &&<br class="">
>>> -      !SkippedChecks.has(<wbr class="">SanitizerKind::Vptr) &&<br class="">
>>> +      !SkippedChecks.has(<wbr class="">SanitizerKind::Vptr) && HasNullCheck &&<br class="">
>>>       (TCK == TCK_MemberAccess || TCK == TCK_MemberCall ||<br class="">
>>>        TCK == TCK_DowncastPointer || TCK == TCK_DowncastReference ||<br class="">
>>>        TCK == TCK_UpcastToVirtualBase) &&<br class="">
>>>       RD && RD->hasDefinition() && RD->isDynamicClass()) {<br class="">
>>> +    // Ensure that the pointer is non-null before loading it. If there is<br class="">
>>> no<br class="">
>>> +    // compile-time guarantee, reuse the run-time null check.<br class="">
>>> +    if (!IsGuaranteedNonNull) {<br class="">
>>> +      assert(IsNonNull && "Missing run-time null check");<br class="">
>>> +      if (!Done)<br class="">
>>> +        Done = createBasicBlock("vptr.null");<br class="">
>>> +      llvm::BasicBlock *VptrNotNull = createBasicBlock("vptr.not.<wbr class="">null");<br class="">
>>> +      Builder.CreateCondBr(<wbr class="">IsNonNull, VptrNotNull, Done);<br class="">
>>> +      EmitBlock(VptrNotNull);<br class="">
>>> +    }<br class="">
>>> +<br class="">
>>>     // Compute a hash of the mangled name of the type.<br class="">
>>>     //<br class="">
>>>     // FIXME: This is not guaranteed to be deterministic! Move to a<br class="">
>>><br class="">
>>> Modified: cfe/trunk/lib/Driver/<wbr class="">SanitizerArgs.cpp<br class="">
>>> URL:<br class="">
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/SanitizerArgs.cpp?rev=309007&r1=309006&r2=309007&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/Driver/<wbr class="">SanitizerArgs.cpp?rev=309007&<wbr class="">r1=309006&r2=309007&view=diff</a><br class="">
>>><br class="">
>>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>>> --- cfe/trunk/lib/Driver/<wbr class="">SanitizerArgs.cpp (original)<br class="">
>>> +++ cfe/trunk/lib/Driver/<wbr class="">SanitizerArgs.cpp Tue Jul 25 12:34:23 2017<br class="">
>>> @@ -306,6 +306,13 @@ SanitizerArgs::SanitizerArgs(<wbr class="">const ToolC<br class="">
>>>     Kinds &= ~Vptr;<br class="">
>>>   }<br class="">
>>><br class="">
>>> +  // Disable -fsanitize=vptr if -fsanitize=null is not enabled (the vptr<br class="">
>>> +  // instrumentation is broken without run-time null checks).<br class="">
>>> +  if ((Kinds & Vptr) && !(Kinds & Null)) {<br class="">
>>> +    Kinds &= ~Vptr;<br class="">
>>> +    D.Diag(diag::warn_drv_<wbr class="">disabling_vptr_no_null_check);<br class="">
>>> +  }<br class="">
>>> +<br class="">
>>>   // Check that LTO is enabled if we need it.<br class="">
>>>   if ((Kinds & NeedsLTO) && !D.isUsingLTO()) {<br class="">
>>>     D.Diag(diag::err_drv_argument_<wbr class="">only_allowed_with)<br class="">
>>><br class="">
>>> Modified: cfe/trunk/test/CodeGenCXX/<wbr class="">catch-undef-behavior.cpp<br class="">
>>> URL:<br class="">
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp?rev=309007&r1=309006&r2=309007&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">CodeGenCXX/catch-undef-<wbr class="">behavior.cpp?rev=309007&r1=<wbr class="">309006&r2=309007&view=diff</a><br class="">
>>><br class="">
>>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>>> --- cfe/trunk/test/CodeGenCXX/<wbr class="">catch-undef-behavior.cpp (original)<br class="">
>>> +++ cfe/trunk/test/CodeGenCXX/<wbr class="">catch-undef-behavior.cpp Tue Jul 25 12:34:23<br class="">
>>> 2017<br class="">
>>> @@ -1,6 +1,6 @@<br class="">
>>> // RUN: %clang_cc1 -std=c++11<br class="">
>>> -fsanitize=signed-integer-<wbr class="">overflow,integer-divide-by-<wbr class="">zero,float-divide-by-zero,<wbr class="">shift-base,shift-exponent,<wbr class="">unreachable,return,vla-bound,<wbr class="">alignment,null,vptr,object-<wbr class="">size,float-cast-overflow,bool,<wbr class="">enum,array-bounds,function<br class="">
>>> -fsanitize-recover=signed-<wbr class="">integer-overflow,integer-<wbr class="">divide-by-zero,float-divide-<wbr class="">by-zero,shift-base,shift-<wbr class="">exponent,vla-bound,alignment,<wbr class="">null,vptr,object-size,float-<wbr class="">cast-overflow,bool,enum,array-<wbr class="">bounds,function<br class="">
>>> -emit-llvm %s -o - -triple x86_64-linux-gnu | opt -instnamer -S | FileCheck<br class="">
>>> %s<br class="">
>>> -// RUN: %clang_cc1 -std=c++11 -fsanitize=vptr,address<br class="">
>>> -fsanitize-recover=vptr,<wbr class="">address -emit-llvm %s -o - -triple x86_64-linux-gnu<br class="">
>>> | FileCheck %s --check-prefix=CHECK-ASAN<br class="">
>>> -// RUN: %clang_cc1 -std=c++11 -fsanitize=vptr -fsanitize-recover=vptr<br class="">
>>> -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s<br class="">
>>> --check-prefix=DOWNCAST-NULL<br class="">
>>> +// RUN: %clang_cc1 -std=c++11 -fsanitize=null,vptr,address<br class="">
>>> -fsanitize-recover=null,vptr,<wbr class="">address -emit-llvm %s -o - -triple<br class="">
>>> x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-ASAN<br class="">
>>> +// RUN: %clang_cc1 -std=c++11 -fsanitize=null,vptr<br class="">
>>> -fsanitize-recover=null,vptr -emit-llvm %s -o - -triple x86_64-linux-gnu |<br class="">
>>> FileCheck %s --check-prefix=DOWNCAST-NULL<br class="">
>>> // RUN: %clang_cc1 -std=c++11 -fsanitize=function -emit-llvm %s -o -<br class="">
>>> -triple x86_64-linux-gnux32 | FileCheck %s --check-prefix=CHECK-X32<br class="">
>>> // RUN: %clang_cc1 -std=c++11 -fsanitize=function -emit-llvm %s -o -<br class="">
>>> -triple i386-linux-gnu | FileCheck %s --check-prefix=CHECK-X86<br class="">
>>><br class="">
>>><br class="">
>>> Modified: cfe/trunk/test/CodeGenCXX/<wbr class="">ubsan-devirtualized-calls.cpp<br class="">
>>> URL:<br class="">
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/ubsan-devirtualized-calls.cpp?rev=309007&r1=309006&r2=309007&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">CodeGenCXX/ubsan-<wbr class="">devirtualized-calls.cpp?rev=<wbr class="">309007&r1=309006&r2=309007&<wbr class="">view=diff</a><br class="">
>>><br class="">
>>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>>> --- cfe/trunk/test/CodeGenCXX/<wbr class="">ubsan-devirtualized-calls.cpp (original)<br class="">
>>> +++ cfe/trunk/test/CodeGenCXX/<wbr class="">ubsan-devirtualized-calls.cpp Tue Jul 25<br class="">
>>> 12:34:23 2017<br class="">
>>> @@ -1,4 +1,4 @@<br class="">
>>> -// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm<br class="">
>>> -fsanitize=vptr %s -o - | FileCheck %s<br class="">
>>> +// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm<br class="">
>>> -fsanitize=null,vptr %s -o - | FileCheck %s<br class="">
>>><br class="">
>>> struct Base1 {<br class="">
>>>   virtual void f1() {}<br class="">
>>> @@ -64,6 +64,11 @@ void t4() {<br class="">
>>>   // CHECK-NEXT: call void<br class="">
>>> @__ubsan_handle_dynamic_type_<wbr class="">cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED3]]<br class="">
>>> {{.*}}, i{{[0-9]+}} %[[P1]]<br class="">
>>><br class="">
>>>   static_cast<Base1 *>(badp)->f1(); //< No devirt, test 'badp isa Base1'.<br class="">
>>> +  // We were able to skip the null check on the first type check because<br class="">
>>> 'p'<br class="">
>>> +  // is backed by an alloca. We can't skip the second null check because<br class="">
>>> 'badp'<br class="">
>>> +  // is a (bitcast (load ...)).<br class="">
>>> +  // CHECK: call void @__ubsan_handle_type_mismatch<br class="">
>>> +  //<br class="">
>>>   // CHECK: %[[BADP1:[0-9]+]] = ptrtoint %struct.Base1* {{%[0-9]+}} to<br class="">
>>> i{{[0-9]+}}, !nosanitize<br class="">
>>>   // CHECK-NEXT: call void<br class="">
>>> @__ubsan_handle_dynamic_type_<wbr class="">cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_BASE1]]<br class="">
>>> {{.*}}, i{{[0-9]+}} %[[BADP1]]<br class="">
>>> }<br class="">
>>> @@ -76,6 +81,8 @@ void t5() {<br class="">
>>>   // CHECK-NEXT: call void<br class="">
>>> @__ubsan_handle_dynamic_type_<wbr class="">cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED4_1]]<br class="">
>>> {{.*}}, i{{[0-9]+}} %[[P1]]<br class="">
>>><br class="">
>>>   static_cast<Base1 *>(badp)->f1(); //< Devirt Base1::f1 to Derived4::f1.<br class="">
>>> +  // CHECK: call void @__ubsan_handle_type_mismatch<br class="">
>>> +  //<br class="">
>>>   // CHECK: %[[BADP1:[0-9]+]] = ptrtoint %struct.Derived4* {{%[0-9]+}} to<br class="">
>>> i{{[0-9]+}}, !nosanitize<br class="">
>>>   // CHECK-NEXT: call void<br class="">
>>> @__ubsan_handle_dynamic_type_<wbr class="">cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED4_2]]<br class="">
>>> {{.*}}, i{{[0-9]+}} %[[BADP1]]<br class="">
>>> }<br class="">
>>><br class="">
>>> Modified: cfe/trunk/test/CodeGenCXX/<wbr class="">ubsan-type-checks.cpp<br class="">
>>> URL:<br class="">
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/ubsan-type-checks.cpp?rev=309007&r1=309006&r2=309007&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">CodeGenCXX/ubsan-type-checks.<wbr class="">cpp?rev=309007&r1=309006&r2=<wbr class="">309007&view=diff</a><br class="">
>>><br class="">
>>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>>> --- cfe/trunk/test/CodeGenCXX/<wbr class="">ubsan-type-checks.cpp (original)<br class="">
>>> +++ cfe/trunk/test/CodeGenCXX/<wbr class="">ubsan-type-checks.cpp Tue Jul 25 12:34:23<br class="">
>>> 2017<br class="">
>>> @@ -1,6 +1,8 @@<br class="">
>>> // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o<br class="">
>>> - %s -fsanitize=alignment | FileCheck %s -check-prefixes=ALIGN,COMMON<br class="">
>>> // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o<br class="">
>>> - %s -fsanitize=null | FileCheck %s -check-prefixes=NULL,COMMON<br class="">
>>> // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o<br class="">
>>> - %s -fsanitize=object-size | FileCheck %s -check-prefixes=OBJSIZE,COMMON<br class="">
>>> +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o<br class="">
>>> - %s -fsanitize=null,vptr | FileCheck %s -check-prefixes=VPTR<br class="">
>>> +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o<br class="">
>>> - %s -fsanitize=vptr | FileCheck %s -check-prefixes=VPTR_NO_NULL<br class="">
>>><br class="">
>>> struct A {<br class="">
>>>   // COMMON-LABEL: define linkonce_odr void @_ZN1A10do_nothingEv<br class="">
>>> @@ -24,13 +26,55 @@ struct B {<br class="">
>>>     // NULL: icmp ne %struct.B* %{{.*}}, null, !nosanitize<br class="">
>>><br class="">
>>>     // OBJSIZE-NOT: call i64 @llvm.objectsize<br class="">
>>> +    // OBJSIZE: ret void<br class="">
>>>   }<br class="">
>>> };<br class="">
>>><br class="">
>>> -void force_irgen() {<br class="">
>>> +struct Animal {<br class="">
>>> +  virtual const char *speak() = 0;<br class="">
>>> +};<br class="">
>>> +<br class="">
>>> +struct Cat : Animal {<br class="">
>>> +  const char *speak() override { return "meow"; }<br class="">
>>> +};<br class="">
>>> +<br class="">
>>> +struct Dog : Animal {<br class="">
>>> +  const char *speak() override { return "woof"; }<br class="">
>>> +};<br class="">
>>> +<br class="">
>>> +// VPTR-LABEL: define void @_Z12invalid_castP3Cat<br class="">
>>> +void invalid_cast(Cat *cat = nullptr) {<br class="">
>>> +  // First, null check the pointer:<br class="">
>>> +  //<br class="">
>>> +  // VPTR: [[ICMP:%.*]] = icmp ne %struct.Dog* {{.*}}, null<br class="">
>>> +  // VPTR-NEXT: br i1 [[ICMP]]<br class="">
>>> +  // VPTR: call void @__ubsan_handle_type_mismatch<br class="">
>>> +  //<br class="">
>>> +  // Once we're done emitting the null check, reuse the check to see if<br class="">
>>> we can<br class="">
>>> +  // proceed to the vptr check:<br class="">
>>> +  //<br class="">
>>> +  // VPTR: br i1 [[ICMP]]<br class="">
>>> +  // VPTR: call void @__ubsan_handle_dynamic_type_<wbr class="">cache_miss<br class="">
>>> +  auto *badDog = reinterpret_cast<Dog *>(cat);<br class="">
>>> +  badDog->speak();<br class="">
>>> +}<br class="">
>>> +<br class="">
>>> +// VPTR_NO_NULL-LABEL: define void @_Z13invalid_cast2v<br class="">
>>> +void invalid_cast2() {<br class="">
>>> +  // We've got a pointer to an alloca, so there's no run-time null check<br class="">
>>> needed.<br class="">
>>> +  // VPTR_NO_NULL-NOT: call void @__ubsan_handle_type_mismatch<br class="">
>>> +  // VPTR_NO_NULL: call void @__ubsan_handle_dynamic_type_<wbr class="">cache_miss<br class="">
>>> +  Cat cat;<br class="">
>>> +  cat.speak();<br class="">
>>> +}<br class="">
>>> +<br class="">
>>> +int main() {<br class="">
>>>   A a;<br class="">
>>>   a.do_nothing();<br class="">
>>><br class="">
>>>   B b;<br class="">
>>>   b.do_nothing();<br class="">
>>> +<br class="">
>>> +  invalid_cast();<br class="">
>>> +  return 0;<br class="">
>>> }<br class="">
>>><br class="">
>>> Modified: cfe/trunk/test/CodeGenCXX/<wbr class="">ubsan-vtable-checks.cpp<br class="">
>>> URL:<br class="">
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/ubsan-vtable-checks.cpp?rev=309007&r1=309006&r2=309007&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">CodeGenCXX/ubsan-vtable-<wbr class="">checks.cpp?rev=309007&r1=<wbr class="">309006&r2=309007&view=diff</a><br class="">
>>><br class="">
>>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>>> --- cfe/trunk/test/CodeGenCXX/<wbr class="">ubsan-vtable-checks.cpp (original)<br class="">
>>> +++ cfe/trunk/test/CodeGenCXX/<wbr class="">ubsan-vtable-checks.cpp Tue Jul 25 12:34:23<br class="">
>>> 2017<br class="">
>>> @@ -1,7 +1,7 @@<br class="">
>>> // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm<br class="">
>>> -fsanitize=null %s -o - | FileCheck %s --check-prefix=CHECK<br class="">
>>> --check-prefix=CHECK-NULL --check-prefix=ITANIUM<br class="">
>>> // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm<br class="">
>>> -fsanitize=null %s -o - | FileCheck %s --check-prefix=CHECK<br class="">
>>> --check-prefix=CHECK-NULL --check-prefix=MSABI<br class="">
>>> -// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm<br class="">
>>> -fsanitize=vptr %s -o - | FileCheck %s --check-prefix=CHECK<br class="">
>>> --check-prefix=CHECK-VPTR --check-prefix=ITANIUM<br class="">
>>> -// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm<br class="">
>>> -fsanitize=vptr %s -o - | FileCheck %s --check-prefix=CHECK<br class="">
>>> --check-prefix=CHECK-VPTR --check-prefix=MSABI<br class="">
>>> +// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm<br class="">
>>> -fsanitize=null,vptr %s -o - | FileCheck %s --check-prefix=CHECK<br class="">
>>> --check-prefix=CHECK-VPTR --check-prefix=ITANIUM<br class="">
>>> +// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm<br class="">
>>> -fsanitize=null,vptr %s -o - | FileCheck %s --check-prefix=CHECK<br class="">
>>> --check-prefix=CHECK-VPTR --check-prefix=MSABI<br class="">
>>> struct T {<br class="">
>>>   virtual ~T() {}<br class="">
>>>   virtual int v() { return 1; }<br class="">
>>><br class="">
>>> Modified: cfe/trunk/test/Driver/<wbr class="">fsanitize.c<br class="">
>>> URL:<br class="">
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/fsanitize.c?rev=309007&r1=309006&r2=309007&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/Driver/<wbr class="">fsanitize.c?rev=309007&r1=<wbr class="">309006&r2=309007&view=diff</a><br class="">
>>><br class="">
>>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>>> --- cfe/trunk/test/Driver/<wbr class="">fsanitize.c (original)<br class="">
>>> +++ cfe/trunk/test/Driver/<wbr class="">fsanitize.c Tue Jul 25 12:34:23 2017<br class="">
>>> @@ -58,6 +58,10 @@<br class="">
>>> // RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fno-rtti %s<br class="">
>>> -### 2>&1 | FileCheck %s --check-prefix=CHECK-<wbr class="">UNDEFINED-NO-RTTI<br class="">
>>> // CHECK-UNDEFINED-NO-RTTI-NOT: vptr<br class="">
>>><br class="">
>>> +// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined<br class="">
>>> -fno-sanitize=null %s -### 2>&1 | FileCheck %s<br class="">
>>> --check-prefix=CHECK-VPTR-NO-<wbr class="">NULL<br class="">
>>> +// RUN: %clang -target x86_64-linux-gnu -fsanitize=vptr %s -### 2>&1 |<br class="">
>>> FileCheck %s --check-prefix=CHECK-VPTR-NO-<wbr class="">NULL<br class="">
>>> +// CHECK-VPTR-NO-NULL: warning: implicitly disabling vptr sanitizer<br class="">
>>> because null checking wasn't enabled<br class="">
>>> +<br class="">
>>> // RUN: %clang -target x86_64-linux-gnu -fsanitize=address,thread<br class="">
>>> -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANA-SANT<br class="">
>>> // CHECK-SANA-SANT: '-fsanitize=address' not allowed with<br class="">
>>> '-fsanitize=thread'<br class="">
>>><br class="">
>>> @@ -362,8 +366,8 @@<br class="">
>>> // RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.8<br class="">
>>> -fsanitize=vptr %s -### 2>&1 | FileCheck %s<br class="">
>>> --check-prefix=CHECK-VPTR-<wbr class="">DARWIN-OLD<br class="">
>>> // CHECK-VPTR-DARWIN-OLD: unsupported option '-fsanitize=vptr' for target<br class="">
>>> 'x86_64-apple-darwin10'<br class="">
>>><br class="">
>>> -// RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.9<br class="">
>>> -fsanitize=alignment,vptr %s -### 2>&1 | FileCheck %s<br class="">
>>> --check-prefix=CHECK-VPTR-<wbr class="">DARWIN-NEW<br class="">
>>> -// CHECK-VPTR-DARWIN-NEW: -fsanitize=alignment,vptr<br class="">
>>> +// RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.9<br class="">
>>> -fsanitize=alignment,null,vptr %s -### 2>&1 | FileCheck %s<br class="">
>>> --check-prefix=CHECK-VPTR-<wbr class="">DARWIN-NEW<br class="">
>>> +// CHECK-VPTR-DARWIN-NEW: -fsanitize=alignment,null,vptr<br class="">
>>><br class="">
>>> // RUN: %clang -target armv7-apple-ios7 -miphoneos-version-min=7.0<br class="">
>>> -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-IOS<br class="">
>>> // CHECK-ASAN-IOS: -fsanitize=address<br class="">
>>><br class="">
>>> Modified: cfe/trunk/test/Driver/rtti-<wbr class="">options.cpp<br class="">
>>> URL:<br class="">
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/rtti-options.cpp?rev=309007&r1=309006&r2=309007&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/Driver/<wbr class="">rtti-options.cpp?rev=309007&<wbr class="">r1=309006&r2=309007&view=diff</a><br class="">
>>><br class="">
>>> ==============================<wbr class="">==============================<wbr class="">==================<br class="">
>>> --- cfe/trunk/test/Driver/rtti-<wbr class="">options.cpp (original)<br class="">
>>> +++ cfe/trunk/test/Driver/rtti-<wbr class="">options.cpp Tue Jul 25 12:34:23 2017<br class="">
>>> @@ -16,14 +16,14 @@<br class="">
>>> // Make sure we only error/warn once, when trying to enable vptr and<br class="">
>>> // undefined and have -fno-rtti<br class="">
>>> // RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=undefined<br class="">
>>> -fsanitize=vptr -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR<br class="">
>>> -check-prefix=CHECK-OK %s<br class="">
>>> -// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=vptr %s<br class="">
>>> 2>&1 | FileCheck -check-prefix=CHECK-OK %s<br class="">
>>> -// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=vptr<br class="">
>>> -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s<br class="">
>>> -// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=vptr<br class="">
>>> -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR %s<br class="">
>>> +// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=null,vptr<br class="">
>>> %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s<br class="">
>>> +// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=null,vptr<br class="">
>>> -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s<br class="">
>>> +// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=null,vptr<br class="">
>>> -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR %s<br class="">
>>> // RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=undefined<br class="">
>>> %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s<br class="">
>>> // RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=undefined<br class="">
>>> -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s<br class="">
>>> -// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=vptr %s 2>&1 |<br class="">
>>> FileCheck -check-prefix=CHECK-SAN-WARN %s<br class="">
>>> -// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=vptr -frtti %s<br class="">
>>> 2>&1 | FileCheck -check-prefix=CHECK-OK %s<br class="">
>>> -// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=vptr -fno-rtti<br class="">
>>> %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR %s<br class="">
>>> +// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=null,vptr %s<br class="">
>>> 2>&1 | FileCheck -check-prefix=CHECK-SAN-WARN %s<br class="">
>>> +// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=null,vptr<br class="">
>>> -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s<br class="">
>>> +// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=null,vptr<br class="">
>>> -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR %s<br class="">
>>> // RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=undefined<br class="">
>>> -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s<br class="">
>>><br class="">
>>> // Exceptions + no/default rtti<br class="">
>>><br class="">
>>><br class="">
>>> ______________________________<wbr class="">_________________<br class="">
>>> cfe-commits mailing list<br class="">
>>> <a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a><br class="">
>>> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/<wbr class="">mailman/listinfo/cfe-commits</a><br class="">
>><br class="">
>><br class="">
>><br class="">
>> ______________________________<wbr class="">_________________<br class="">
>> cfe-commits mailing list<br class="">
>> <a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a><br class="">
>> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/<wbr class="">mailman/listinfo/cfe-commits</a><br class="">
>><br class="">
<br class="">
</div></div></blockquote></div><br class=""></div></div>
</div></blockquote></div><br class=""></body></html>