diff options
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 13 | ||||
-rw-r--r-- | clang/test/Sema/warn-absolute-value.c | 20 |
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}} +} |