[cfe-commits] r170108 - in /cfe/trunk: docs/UsersManual.rst include/clang/Basic/Sanitizers.def lib/CodeGen/CGExpr.cpp test/CodeGen/catch-undef-behavior.c test/CodeGenCXX/catch-undef-behavior.cpp test/Driver/fsanitize.c
Rafael EspĂndola
rafael.espindola at gmail.com
Thu Dec 13 06:20:29 PST 2012
Awesome!
On 13 December 2012 02:11, Richard Smith <richard-llvm at metafoo.co.uk> wrote:
> Author: rsmith
> Date: Thu Dec 13 01:11:50 2012
> New Revision: 170108
>
> URL: http://llvm.org/viewvc/llvm-project?rev=170108&view=rev
> Log:
> ubsan: Add -fsanitize=bool and -fsanitize=enum, which check for loads of
> bit-patterns which are not valid values for enumerated or boolean types.
> These checks are the ubsan analogue of !range metadata.
>
> Modified:
> cfe/trunk/docs/UsersManual.rst
> cfe/trunk/include/clang/Basic/Sanitizers.def
> cfe/trunk/lib/CodeGen/CGExpr.cpp
> cfe/trunk/test/CodeGen/catch-undef-behavior.c
> cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp
> cfe/trunk/test/Driver/fsanitize.c
>
> Modified: cfe/trunk/docs/UsersManual.rst
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UsersManual.rst?rev=170108&r1=170107&r2=170108&view=diff
> ==============================================================================
> --- cfe/trunk/docs/UsersManual.rst (original)
> +++ cfe/trunk/docs/UsersManual.rst Thu Dec 13 01:11:50 2012
> @@ -834,8 +834,13 @@
>
> - ``-fsanitize=alignment``: Use of a misaligned pointer or creation
> of a misaligned reference.
> + - ``-fsanitize=bool``: Load of a ``bool`` value which is neither
> + ``true`` nor ``false``.
> - ``-fsanitize=bounds``: Out of bounds array indexing, in cases
> where the array bound can be statically determined.
> + - ``-fsanitize=enum``: Load of a value of an enumerated type which
> + is not in the range of representable values for that enumerated
> + type.
> - ``-fsanitize=float-cast-overflow``: Conversion to, from, or
> between floating-point types which would overflow the
> destination.
>
> Modified: cfe/trunk/include/clang/Basic/Sanitizers.def
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Sanitizers.def?rev=170108&r1=170107&r2=170108&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/Sanitizers.def (original)
> +++ cfe/trunk/include/clang/Basic/Sanitizers.def Thu Dec 13 01:11:50 2012
> @@ -56,7 +56,9 @@
>
> // UndefinedBehaviorSanitizer
> SANITIZER("alignment", Alignment)
> +SANITIZER("bool", Bool)
> SANITIZER("bounds", Bounds)
> +SANITIZER("enum", Enum)
> SANITIZER("float-cast-overflow", FloatCastOverflow)
> SANITIZER("float-divide-by-zero", FloatDivideByZero)
> SANITIZER("integer-divide-by-zero", IntegerDivideByZero)
> @@ -76,9 +78,10 @@
> // include all the sanitizers which have low overhead, no ABI or address space
> // layout implications, and only catch undefined behavior.
> SANITIZER_GROUP("undefined", Undefined,
> - Alignment | Bounds | FloatCastOverflow | FloatDivideByZero |
> - IntegerDivideByZero | Null | ObjectSize | Return | Shift |
> - SignedIntegerOverflow | Unreachable | VLABound | Vptr)
> + Alignment | Bool | Bounds | Enum | FloatCastOverflow |
> + FloatDivideByZero | IntegerDivideByZero | Null | ObjectSize |
> + Return | Shift | SignedIntegerOverflow | Unreachable |
> + VLABound | Vptr)
>
> SANITIZER_GROUP("integer", Integer,
> SignedIntegerOverflow | UnsignedIntegerOverflow | Shift |
>
> Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=170108&r1=170107&r2=170108&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Thu Dec 13 01:11:50 2012
> @@ -924,23 +924,22 @@
> return false;
> }
>
> -llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {
> +static bool getRangeForType(CodeGenFunction &CGF, QualType Ty,
> + llvm::APInt &Min, llvm::APInt &End,
> + bool StrictEnums) {
> const EnumType *ET = Ty->getAs<EnumType>();
> - bool IsRegularCPlusPlusEnum = (getLangOpts().CPlusPlus && ET &&
> - CGM.getCodeGenOpts().StrictEnums &&
> - !ET->getDecl()->isFixed());
> + bool IsRegularCPlusPlusEnum = CGF.getLangOpts().CPlusPlus && StrictEnums &&
> + ET && !ET->getDecl()->isFixed();
> bool IsBool = hasBooleanRepresentation(Ty);
> if (!IsBool && !IsRegularCPlusPlusEnum)
> - return NULL;
> + return false;
>
> - llvm::APInt Min;
> - llvm::APInt End;
> if (IsBool) {
> - Min = llvm::APInt(getContext().getTypeSize(Ty), 0);
> - End = llvm::APInt(getContext().getTypeSize(Ty), 2);
> + Min = llvm::APInt(CGF.getContext().getTypeSize(Ty), 0);
> + End = llvm::APInt(CGF.getContext().getTypeSize(Ty), 2);
> } else {
> const EnumDecl *ED = ET->getDecl();
> - llvm::Type *LTy = ConvertTypeForMem(ED->getIntegerType());
> + llvm::Type *LTy = CGF.ConvertTypeForMem(ED->getIntegerType());
> unsigned Bitwidth = LTy->getScalarSizeInBits();
> unsigned NumNegativeBits = ED->getNumNegativeBits();
> unsigned NumPositiveBits = ED->getNumPositiveBits();
> @@ -956,6 +955,14 @@
> Min = llvm::APInt(Bitwidth, 0);
> }
> }
> + return true;
> +}
> +
> +llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {
> + llvm::APInt Min, End;
> + if (!getRangeForType(*this, Ty, Min, End,
> + CGM.getCodeGenOpts().StrictEnums))
> + return 0;
>
> llvm::MDBuilder MDHelper(getLLVMContext());
> return MDHelper.createRange(Min, End);
> @@ -1014,7 +1021,27 @@
> if (Ty->isAtomicType())
> Load->setAtomic(llvm::SequentiallyConsistent);
>
> - if (CGM.getCodeGenOpts().OptimizationLevel > 0)
> + if ((getLangOpts().SanitizeBool && hasBooleanRepresentation(Ty)) ||
> + (getLangOpts().SanitizeEnum && Ty->getAs<EnumType>())) {
> + llvm::APInt Min, End;
> + if (getRangeForType(*this, Ty, Min, End, true)) {
> + --End;
> + llvm::Value *Check;
> + if (!Min)
> + Check = Builder.CreateICmpULE(
> + Load, llvm::ConstantInt::get(getLLVMContext(), End));
> + else {
> + llvm::Value *Upper = Builder.CreateICmpSLE(
> + Load, llvm::ConstantInt::get(getLLVMContext(), End));
> + llvm::Value *Lower = Builder.CreateICmpSGE(
> + Load, llvm::ConstantInt::get(getLLVMContext(), Min));
> + Check = Builder.CreateAnd(Upper, Lower);
> + }
> + // FIXME: Provide a SourceLocation.
> + EmitCheck(Check, "load_invalid_value", EmitCheckTypeDescriptor(Ty),
> + EmitCheckValue(Load), CRK_Recoverable);
> + }
> + } else if (CGM.getCodeGenOpts().OptimizationLevel > 0)
> if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty))
> Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo);
>
>
> Modified: cfe/trunk/test/CodeGen/catch-undef-behavior.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/catch-undef-behavior.c?rev=170108&r1=170107&r2=170108&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGen/catch-undef-behavior.c (original)
> +++ cfe/trunk/test/CodeGen/catch-undef-behavior.c Thu Dec 13 01:11:50 2012
> @@ -1,4 +1,4 @@
> -// RUN: %clang_cc1 -fsanitize=alignment,null,object-size,shift,return,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
> +// RUN: %clang_cc1 -fsanitize=alignment,null,object-size,shift,return,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
> // RUN: %clang_cc1 -fsanitize=null -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-NULL
> // RUN: %clang_cc1 -fsanitize=signed-integer-overflow -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-OVERFLOW
>
> @@ -246,3 +246,11 @@
> // CHECK: }
> // CHECK-OVERFLOW: }
> }
> +
> +// CHECK: @sour_bool
> +_Bool sour_bool(_Bool *p) {
> + // CHECK: %[[OK:.*]] = icmp ule i8 {{.*}}, 1
> + // CHECK: br i1 %[[OK]]
> + // CHECK: call void @__ubsan_handle_load_invalid_value_abort(i8* bitcast ({{.*}}), i64 {{.*}})
> + return *p;
> +}
>
> 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=170108&r1=170107&r2=170108&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp (original)
> +++ cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp Thu Dec 13 01:11:50 2012
> @@ -1,4 +1,4 @@
> -// RUN: %clang_cc1 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
> +// RUN: %clang_cc1 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
>
> // CHECK: @_Z17reference_binding
> void reference_binding(int *p) {
> @@ -136,3 +136,36 @@
> // CHECK: call void @__ubsan_handle_missing_return(i8* bitcast ({{.*}}* @{{.*}} to i8*)) noreturn nounwind
> // CHECK-NEXT: unreachable
> }
> +
> +// CHECK: @_Z9sour_bool
> +bool sour_bool(bool *p) {
> + // CHECK: %[[OK:.*]] = icmp ule i8 {{.*}}, 1
> + // CHECK: br i1 %[[OK]]
> + // CHECK: call void @__ubsan_handle_load_invalid_value_abort(i8* bitcast ({{.*}}), i64 {{.*}})
> + return *p;
> +}
> +
> +enum E1 { e1a = 0, e1b = 127 } e1;
> +enum E2 { e2a = -1, e2b = 64 } e2;
> +enum E3 { e3a = (1u << 31) - 1 } e3;
> +
> +// CHECK: @_Z14bad_enum_value
> +int bad_enum_value() {
> + // CHECK: %[[E1:.*]] = icmp ule i32 {{.*}}, 127
> + // CHECK: br i1 %[[E1]]
> + // CHECK: call void @__ubsan_handle_load_invalid_value_abort(
> + int a = e1;
> +
> + // CHECK: %[[E2HI:.*]] = icmp sle i32 {{.*}}, 127
> + // CHECK: %[[E2LO:.*]] = icmp sge i32 {{.*}}, -128
> + // CHECK: %[[E2:.*]] = and i1 %[[E2HI]], %[[E2LO]]
> + // CHECK: br i1 %[[E2]]
> + // CHECK: call void @__ubsan_handle_load_invalid_value_abort(
> + int b = e2;
> +
> + // CHECK: %[[E3:.*]] = icmp ule i32 {{.*}}, 2147483647
> + // CHECK: br i1 %[[E3]]
> + // CHECK: call void @__ubsan_handle_load_invalid_value_abort(
> + int c = e3;
> + return a + b + c;
> +}
>
> Modified: cfe/trunk/test/Driver/fsanitize.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/fsanitize.c?rev=170108&r1=170107&r2=170108&view=diff
> ==============================================================================
> --- cfe/trunk/test/Driver/fsanitize.c (original)
> +++ cfe/trunk/test/Driver/fsanitize.c Thu Dec 13 01:11:50 2012
> @@ -1,13 +1,11 @@
> // RUN: %clang -target x86_64-linux-gnu -fcatch-undefined-behavior %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED
> // RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED
> +// CHECK-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift|unreachable|return|vla-bound|alignment|null|vptr|object-size|float-cast-overflow|bounds|enum|bool),?){15}"}}
>
> -// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread,undefined -fno-thread-sanitizer -fno-sanitize=float-cast-overflow,vptr %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-PARTIAL-UNDEFINED
> -// CHECK-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift|unreachable|return|vla-bound|alignment|null|vptr|object-size|float-cast-overflow|bounds),?){13}"}}
> -//
> // RUN: %clang -target x86_64-linux-gnu -fsanitize=integer %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-INTEGER
> // CHECK-INTEGER: "-fsanitize={{((signed-integer-overflow|unsigned-integer-overflow|integer-divide-by-zero|shift),?){4}"}}
>
> -// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread,undefined -fno-thread-sanitizer -fno-sanitize=float-cast-overflow,vptr %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-PARTIAL-UNDEFINED
> +// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread,undefined -fno-thread-sanitizer -fno-sanitize=float-cast-overflow,vptr,bool,enum %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-PARTIAL-UNDEFINED
> // CHECK-PARTIAL-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift|unreachable|return|vla-bound|alignment|null|object-size|bounds),?){11}"}}
>
> // RUN: %clang -target x86_64-linux-gnu -fsanitize=address-full %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-FULL
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list