aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Stenglein <jstenglein@gmail.com>2020-03-09 10:17:15 -0700
committerErich Keane <erich.keane@intel.com>2020-03-09 10:43:09 -0700
commit843a9778fcd5ef93804fc22de04af9ab8c8b20a9 (patch)
tree4b3f6ebab94fa92f835d992236b1bd2471decd6a
parenteb682b80274d5486d062e3f53040969f592277e4 (diff)
downloadllvm-843a9778fcd5ef93804fc22de04af9ab8c8b20a9.zip
llvm-843a9778fcd5ef93804fc22de04af9ab8c8b20a9.tar.gz
llvm-843a9778fcd5ef93804fc22de04af9ab8c8b20a9.tar.bz2
Add a warning for builtin_return_address/frame_address with > 0 argument
Clang is missing a warning for builtin_return_address/builtin_frame_address called with > 0 argument. Gcc provides a warning for this via -Wframe-address: https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html As calling these functions with argument > 0 has caused several crashes for us, we would like to have the same warning as gcc here. This diff adds the warning and makes it part of -Wmost. Differential Revision: https://reviews.llvm.org/D75768
-rw-r--r--clang/include/clang/Basic/DiagnosticGroups.td2
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td5
-rw-r--r--clang/lib/Sema/SemaChecking.cpp11
-rw-r--r--clang/test/Misc/warning-wall.c1
4 files changed, 19 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index ae3f882..2b11298 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -99,6 +99,7 @@ def FloatConversion :
DiagGroup<"float-conversion", [FloatOverflowConversion,
FloatZeroConversion]>;
+def FrameAddress : DiagGroup<"frame-address">;
def DoublePromotion : DiagGroup<"double-promotion">;
def EnumTooLarge : DiagGroup<"enum-too-large">;
def UnsupportedNan : DiagGroup<"unsupported-nan">;
@@ -872,6 +873,7 @@ def Most : DiagGroup<"most", [
DeleteNonVirtualDtor,
Format,
ForLoopAnalysis,
+ FrameAddress,
Implicit,
InfiniteRecursion,
IntInBoolContext,
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b0338c4..6c73917 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1780,6 +1780,11 @@ def note_due_to_dllexported_class : Note<
def err_illegal_union_or_anon_struct_member : Error<
"%select{anonymous struct|union}0 member %1 has a non-trivial "
"%sub{select_special_member_kind}2">;
+
+def warn_frame_address : Warning<
+ "calling '%0' with a nonzero argument is unsafe">,
+ InGroup<FrameAddress>, DefaultIgnore;
+
def warn_cxx98_compat_nontrivial_union_or_anon_struct_member : Warning<
"%select{anonymous struct|union}0 member %1 with a non-trivial "
"%sub{select_special_member_kind}2 is incompatible with C++98">,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 106e90f..2e73fca 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -1853,6 +1853,17 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
case Builtin::BI__builtin_return_address:
if (SemaBuiltinConstantArgRange(TheCall, 0, 0, 0xFFFF))
return ExprError();
+
+ // -Wframe-address warning if non-zero passed to builtin
+ // return/frame address.
+ Expr::EvalResult Result;
+ if (TheCall->getArg(0)->EvaluateAsInt(Result, getASTContext()) &&
+ Result.Val.getInt() != 0)
+ Diag(TheCall->getBeginLoc(), diag::warn_frame_address)
+ << ((BuiltinID == Builtin::BI__builtin_return_address)
+ ? "__builtin_return_address"
+ : "__builtin_frame_address")
+ << TheCall->getSourceRange();
break;
}
diff --git a/clang/test/Misc/warning-wall.c b/clang/test/Misc/warning-wall.c
index 737ed76..d0a0172 100644
--- a/clang/test/Misc/warning-wall.c
+++ b/clang/test/Misc/warning-wall.c
@@ -16,6 +16,7 @@ CHECK-NEXT: -Wformat-security
CHECK-NEXT: -Wformat-y2k
CHECK-NEXT: -Wformat-invalid-specifier
CHECK-NEXT: -Wfor-loop-analysis
+CHECK-NEXT: -Wframe-address
CHECK-NEXT: -Wimplicit
CHECK-NEXT: -Wimplicit-function-declaration
CHECK-NEXT: -Wimplicit-int