[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