summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-11-15 03:04:34 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-11-15 03:04:34 +0000
commit7f77eb90a54c96168d6cce8ad3a85d1454cdb80c (patch)
tree9209507d1706b1af523846a7b3b30661fc35e8f5
parent07fa1766699ed035a2d5388f7b492c4fd9e54028 (diff)
downloadbcm5719-llvm-7f77eb90a54c96168d6cce8ad3a85d1454cdb80c.tar.gz
bcm5719-llvm-7f77eb90a54c96168d6cce8ad3a85d1454cdb80c.zip
[Sema] Don't crash trying to diagnose abs called on a pointer type
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. llvm-svn: 253156
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--clang/lib/Sema/SemaChecking.cpp13
-rw-r--r--clang/test/Sema/warn-absolute-value.c20
3 files changed, 34 insertions, 2 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index bf1101f0f4c..d0518b98570 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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">,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 5c942273314..24940167be2 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -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)
diff --git a/clang/test/Sema/warn-absolute-value.c b/clang/test/Sema/warn-absolute-value.c
index 70601db63a1..109d515d3b2 100644
--- a/clang/test/Sema/warn-absolute-value.c
+++ b/clang/test/Sema/warn-absolute-value.c
@@ -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}}
+}
OpenPOWER on IntegriCloud