]> granicus.if.org Git - clang/commitdiff
[Sema] Don't crash trying to diagnose abs called on a pointer type
authorDavid Majnemer <david.majnemer@gmail.com>
Sun, 15 Nov 2015 03:04:34 +0000 (03:04 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sun, 15 Nov 2015 03:04:34 +0000 (03:04 +0000)
Clang tries to figure out if a call to abs is suspicious by looking
through implicit casts to look at the underlying, implicitly converted
type.
Interestingly, C has implicit conversions from pointer-ish types like
function to less exciting types like int.  This trips up our 'abs'
checker because it doesn't know which variant of 'abs' is appropriate.

Instead, diagnose 'abs' called on function types upfront.  This sort of
thing is highly suspicious and is likely indicative of a missing
pointer dereference/function call/array index operation.

This fixes PR25532.

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaChecking.cpp
test/Sema/warn-absolute-value.c

index bf1101f0f4cfc430a0a3c16b1fa11b7669a0dc87..d0518b985705930e16753b87c670f400e8fd05d8 100644 (file)
@@ -67,6 +67,9 @@ def warn_wrong_absolute_value_type : Warning<
   "when argument is of %select{integer|floating point|complex}2 type">,
   InGroup<AbsoluteValue>;
 def note_replace_abs_function : Note<"use function '%0' instead">;
+def warn_pointer_abs : Warning<
+  "taking the absolute value of %select{pointer|function|array}0 type %1 is suspicious">,
+  InGroup<AbsoluteValue>;
 
 def warn_infinite_recursive_function : Warning<
   "all paths through this function will call itself">,
index 5c942273314ab5bb990488f6089bbc3cc2d617cd..24940167be2f1a8f269427b1f7085bc7694e2c51 100644 (file)
@@ -5085,6 +5085,19 @@ void Sema::CheckAbsoluteValueFunction(const CallExpr *Call,
     return;
   }
 
+  // Taking the absolute value of a pointer is very suspicious, they probably
+  // wanted to index into an array, dereference a pointer, call a function, etc.
+  if (ArgType->isPointerType() || ArgType->canDecayToPointerType()) {
+    unsigned DiagType = 0;
+    if (ArgType->isFunctionType())
+      DiagType = 1;
+    else if (ArgType->isArrayType())
+      DiagType = 2;
+
+    Diag(Call->getExprLoc(), diag::warn_pointer_abs) << DiagType << ArgType;
+    return;
+  }
+
   // std::abs has overloads which prevent most of the absolute value problems
   // from occurring.
   if (IsStdAbs)
index 70601db63a1f6565502cbabcba575d5d3c1739c5..109d515d3b2b9f573ca208b09bf1d0ab1f12d055 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -verify %s -Wabsolute-value
-// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only %s -Wabsolute-value -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -verify %s -Wabsolute-value -Wno-int-conversion
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only %s -Wabsolute-value -Wno-int-conversion -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s
 
 int abs(int);
 long int labs(long int);
@@ -780,3 +780,19 @@ void test_unsigned_long(unsigned long x) {
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
 }
 
+long long test_array() {
+  return llabs((long long[]){1});
+  // expected-warning@-1 {{absolute value of array type}}
+}
+long long test_function_pointer() {
+  return llabs(&test_function_pointer);
+  // expected-warning@-1 {{absolute value of pointer type}}
+}
+long long test_void_pointer(void *x) {
+  return llabs(x);
+  // expected-warning@-1 {{absolute value of pointer type}}
+}
+long long test_function() {
+  return llabs(test_function);
+  // expected-warning@-1 {{absolute value of function type}}
+}