]> granicus.if.org Git - clang/commitdiff
[clang][CodeGen] ImplicitIntegerSignChangeSanitizer: actually ignore NOP casts.
authorRoman Lebedev <lebedev.ri@gmail.com>
Thu, 1 Nov 2018 08:56:51 +0000 (08:56 +0000)
committerRoman Lebedev <lebedev.ri@gmail.com>
Thu, 1 Nov 2018 08:56:51 +0000 (08:56 +0000)
I fully expected for that to be handled by the canonical type check,
but it clearly wasn't. Sadly, somehow it hide until now.

Reported by Eli Friedman.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@345816 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExprScalar.cpp
test/CodeGen/catch-implicit-integer-sign-changes-true-negatives.c

index ef2999a24da271eca4f78a4c250c4be0f785a0db..0b9a0a45c57d9dd497fd9fc3c6b6083a472245ad 100644 (file)
@@ -1127,10 +1127,9 @@ void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType,
   // Now, we do not need to emit the check in *all* of the cases.
   // We can avoid emitting it in some obvious cases where it would have been
   // dropped by the opt passes (instcombine) always anyways.
-  // If it's a cast between the same type, just differently-sugared. no check.
-  QualType CanonSrcType = CGF.getContext().getCanonicalType(SrcType);
-  QualType CanonDstType = CGF.getContext().getCanonicalType(DstType);
-  if (CanonSrcType == CanonDstType)
+  // If it's a cast between effectively the same type, no check.
+  // NOTE: this is *not* equivalent to checking the canonical types.
+  if (SrcSigned == DstSigned && SrcBits == DstBits)
     return;
   // At least one of the values needs to have signed type.
   // If both are unsigned, then obviously, neither of them can be negative.
index 3798cccdd53d9e3556d053d143f198a080b56abe..b847344818c60014a5f68dd126f4bfab4d953cd1 100644 (file)
@@ -138,3 +138,15 @@ uint32_t unsigned_int_to_uint32(unsigned int src) {
 uint32_t uint32_to_uint32(uint32_t src) {
   return src;
 }
+
+// "Transparent" Enum.
+// ========================================================================== //
+
+enum a { b = ~2147483647 };
+enum a c();
+void d(int);
+void e();
+void e() {
+  enum a f = c();
+  d(f);
+}