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