r190481 - Disable the bool and enum sanitizers when emitting the implicitly-defined copy

Nick Lewycky nicholas at mxc.ca
Tue Sep 10 19:03:20 PDT 2013


Author: nicholas
Date: Tue Sep 10 21:03:20 2013
New Revision: 190481

URL: http://llvm.org/viewvc/llvm-project?rev=190481&view=rev
Log:
Disable the bool and enum sanitizers when emitting the implicitly-defined copy
constructor, copy assignment operator and move assignment operator.

Modified:
    cfe/trunk/lib/CodeGen/CGClass.cpp
    cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=190481&r1=190480&r2=190481&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Tue Sep 10 21:03:20 2013
@@ -741,6 +741,29 @@ void CodeGenFunction::EmitConstructorBod
 }
 
 namespace {
+  /// RAII object to indicate that codegen is copying the value representation
+  /// instead of the object representation. Useful when copying a struct or
+  /// class which has uninitialized members and we're only performing
+  /// lvalue-to-rvalue conversion on the object but not its members.
+  class CopyingValueRepresentation {
+  public:
+    explicit CopyingValueRepresentation(CodeGenFunction &CGF)
+        : CGF(CGF), SO(*CGF.SanOpts), OldSanOpts(CGF.SanOpts) {
+      SO.Bool = false;
+      SO.Enum = false;
+      CGF.SanOpts = &SO;
+    }
+    ~CopyingValueRepresentation() {
+      CGF.SanOpts = OldSanOpts;
+    }
+  private:
+    CodeGenFunction &CGF;
+    SanitizerOptions SO;
+    const SanitizerOptions *OldSanOpts;
+  };
+}
+
+namespace {
   class FieldMemcpyizer {
   public:
     FieldMemcpyizer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl,
@@ -939,9 +962,10 @@ namespace {
       if (AggregatedInits.size() <= 1) {
         // This memcpy is too small to be worthwhile. Fall back on default
         // codegen.
-        for (unsigned i = 0; i < AggregatedInits.size(); ++i) {
+        if (!AggregatedInits.empty()) {
+          CopyingValueRepresentation CVR(CGF);
           EmitMemberInitializer(CGF, ConstructorDecl->getParent(),
-                                AggregatedInits[i], ConstructorDecl, Args);
+                                AggregatedInits[0], ConstructorDecl, Args);
         }
         reset();
         return;
@@ -980,8 +1004,8 @@ namespace {
   private:
 
     // Returns the memcpyable field copied by the given statement, if one
-    // exists. Otherwise r
-    FieldDecl* getMemcpyableField(Stmt *S) {
+    // exists. Otherwise returns null.
+    FieldDecl *getMemcpyableField(Stmt *S) {
       if (!AssignmentsMemcpyable)
         return 0;
       if (BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) {
@@ -1075,8 +1099,10 @@ namespace {
 
     void emitAggregatedStmts() {
       if (AggregatedStmts.size() <= 1) {
-        for (unsigned i = 0; i < AggregatedStmts.size(); ++i)
-          CGF.EmitStmt(AggregatedStmts[i]);
+        if (!AggregatedStmts.empty()) {
+          CopyingValueRepresentation CVR(CGF);
+          CGF.EmitStmt(AggregatedStmts[0]);
+        }
         reset();
       }
 
@@ -1672,8 +1698,7 @@ CodeGenFunction::EmitSynthesizedCXXCopyC
     EmitAggregateCopy(This, Src, (*ArgBeg)->getType());
     return;
   }
-  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, 
-                                                    clang::Ctor_Complete);
+  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, clang::Ctor_Complete);
   assert(D->isInstance() &&
          "Trying to emit a member call expr on a static method!");
   

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=190481&r1=190480&r2=190481&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp Tue Sep 10 21:03:20 2013
@@ -340,7 +340,7 @@ class C : public A, public B // align=16
 // offset. The pointer before subtraction doesn't need to be aligned for
 // the destination type.
 
-// CHECK-LABEL-LABEL: define void @_Z16downcast_pointerP1B(%class.B* %b)
+// CHECK-LABEL: define void @_Z16downcast_pointerP1B(%class.B* %b)
 void downcast_pointer(B *b) {
   (void) static_cast<C*>(b);
   // Alignment check from EmitTypeCheck(TCK_DowncastPointer, ...)
@@ -357,7 +357,7 @@ void downcast_pointer(B *b) {
   // CHECK-NEXT: br i1 [[AND]]
 }
 
-// CHECK-LABEL-LABEL: define void @_Z18downcast_referenceR1B(%class.B* %b)
+// CHECK-LABEL: define void @_Z18downcast_referenceR1B(%class.B* %b)
 void downcast_reference(B &b) {
   (void) static_cast<C&>(b);
   // Alignment check from EmitTypeCheck(TCK_DowncastReference, ...)
@@ -372,4 +372,87 @@ void downcast_reference(B &b) {
   // CHECK-NEXT: br i1 [[AND]]
 }
 
+namespace CopyValueRepresentation {
+  // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S3aSERKS0_
+  // CHECK-NOT: call {{.*}} @__ubsan_handle_load_invalid_value
+  // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S4aSEOS0_
+  // CHECK-NOT: call {{.*}} @__ubsan_handle_load_invalid_value
+  // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S5C2ERKS0_
+  // CHECK-NOT: call {{.*}} __ubsan_handle_load_invalid_value
+  // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S2C2ERKS0_
+  // CHECK: __ubsan_handle_load_invalid_value
+  // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S1C2ERKS0_
+  // CHECK-NOT: call {{.*}} __ubsan_handle_load_invalid_value
+
+  struct CustomCopy { CustomCopy(); CustomCopy(const CustomCopy&); };
+  struct S1 {
+    CustomCopy CC;
+    bool b;
+  };
+  void callee1(S1);
+  void test1() {
+    S1 s11;
+    callee1(s11);
+    S1 s12;
+    s12 = s11;
+  }
+
+  static bool some_global_bool;
+  struct ExprCopy {
+    ExprCopy();
+    ExprCopy(const ExprCopy&, bool b = some_global_bool);
+  };
+  struct S2 {
+    ExprCopy EC;
+    bool b;
+  };
+  void callee2(S2);
+  void test2(void) {
+    S2 s21;
+    callee2(s21);
+    S2 s22;
+    s22 = s21;
+  }
+
+  struct CustomAssign { CustomAssign &operator=(const CustomAssign&); };
+  struct S3 {
+    CustomAssign CA;
+    bool b;
+  };
+  void test3() {
+    S3 x, y;
+    x = y;
+  }
+
+  struct CustomMove {
+    CustomMove();
+    CustomMove(const CustomMove&&);
+    CustomMove &operator=(const CustomMove&&);
+  };
+  struct S4 {
+    CustomMove CM;
+    bool b;
+  };
+  void test4() {
+    S4 x, y;
+    x = static_cast<S4&&>(y);
+  }
+
+  struct EnumCustomCopy {
+    EnumCustomCopy();
+    EnumCustomCopy(const EnumCustomCopy&);
+  };
+  struct S5 {
+    EnumCustomCopy ECC;
+    bool b;
+  };
+  void callee5(S5);
+  void test5() {
+    S5 s51;
+    callee5(s51);
+    S5 s52;
+    s52 = s51;
+  }
+}
+
 // CHECK: attributes [[NR_NUW]] = { noreturn nounwind }





More information about the cfe-commits mailing list