jhenderson created this revision.
Herald added a subscriber: fhahn.

Depends on https://reviews.llvm.org/D29023, which is currently under review. In 
that change, I am adding diagnostic information to LLVM for why Stack Smash 
Protection has been applied to each function. This is the second stage, namely 
adding a new remark to clang, which is emitted when enabled via "-Rssp-reason".


https://reviews.llvm.org/D29027

Files:
  include/clang/Basic/DiagnosticFrontendKinds.td
  include/clang/Basic/DiagnosticGroups.td
  lib/CodeGen/CodeGenAction.cpp
  test/CodeGen/stack-protector-remarks.c

Index: test/CodeGen/stack-protector-remarks.c
===================================================================
--- test/CodeGen/stack-protector-remarks.c
+++ test/CodeGen/stack-protector-remarks.c
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -emit-obj %s -Rssp-reason -stack-protector 2 -o /dev/null 2>&1 | FileCheck %s -check-prefix=CHECK1
+// CHECK1-NOT: no_ssp
+// CHECK1: call to alloca
+// CHECK1-NEXT: alloca_ssp()
+// CHECK1: stack allocated buffer or struct
+// CHECK1-NEXT: buffer_ssp()
+// CHECK1: stack allocated buffer or struct
+// CHECK1-NEXT: struct_ssp()
+// CHECK1: address of a local variable
+// CHECK1-NEXT: address_ssp()
+// CHECK1: stack allocated buffer or struct
+// CHECK1-NEXT: multiple_ssp
+// CHECK1: stack allocated buffer or struct
+// CHECK1: address of a local variable
+// CHECK1: call to alloca
+
+// RUN: %clang_cc1 -emit-obj %s -Rssp-reason -stack-protector 3 -o /dev/null 2>&1 | FileCheck %s -check-prefix=CHECK2
+// CHECK2: function attribute or use of -fstack-protector-all
+// CHECK2-NEXT: no_ssp
+// CHECK2: function attribute or use of -fstack-protector-all
+// CHECK2-NEXT: alloca_ssp()
+// CHECK2: function attribute or use of -fstack-protector-all
+// CHECK2-NEXT: buffer_ssp()
+// CHECK2: function attribute or use of -fstack-protector-all
+// CHECK2-NEXT: struct_ssp()
+// CHECK2: function attribute or use of -fstack-protector-all
+// CHECK2-NEXT: address_ssp()
+// CHECK2: function attribute or use of -fstack-protector-all
+// CHECK2-NEXT: multiple_ssp
+
+void no_ssp() {
+}
+
+void alloca_ssp() {
+  __builtin_alloca(2);
+}
+
+void buffer_ssp() {
+  int x[64];
+}
+
+struct X {
+  int x[64];
+};
+void struct_ssp() {
+  struct X x;
+}
+
+void address_ssp() {
+  int x = 32;
+  int * y = &x;
+}
+
+void multiple_ssp() {
+  struct X x;
+  int y[64];
+  __builtin_alloca(2);
+  int a = 32;
+  int * b = &a;
+}
Index: lib/CodeGen/CodeGenAction.cpp
===================================================================
--- lib/CodeGen/CodeGenAction.cpp
+++ lib/CodeGen/CodeGenAction.cpp
@@ -307,6 +307,9 @@
         const llvm::OptimizationRemarkAnalysisAliasing &D);
     void OptimizationFailureHandler(
         const llvm::DiagnosticInfoOptimizationFailure &D);
+
+    /// \brief Specialized handler for Stack Protector remark diagnostics.
+    void SSPRemarkHandler(const DiagnosticInfoSSP &D);
   };
   
   void BackendConsumer::anchor() {}
@@ -631,6 +634,15 @@
   EmitOptimizationMessage(D, diag::warn_fe_backend_optimization_failure);
 }
 
+void BackendConsumer::SSPRemarkHandler(const DiagnosticInfoSSP &D) {
+  StringRef Filename;
+  unsigned Line, Column;
+  bool BadDebugInfo = false;
+  FullSourceLoc Loc = getBestLocationFromDebugLoc(D, BadDebugInfo, Filename,
+      Line, Column);
+  Diags.Report(Loc, diag::remark_ssp_applied_reason) << D.Reason();
+}
+
 /// \brief This function is invoked when the backend needs
 /// to report something to the user.
 void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) {
@@ -688,6 +700,9 @@
   case llvm::DK_Unsupported:
     UnsupportedDiagHandler(cast<DiagnosticInfoUnsupported>(DI));
     return;
+  case llvm::DK_SSPReason:
+    SSPRemarkHandler(cast<DiagnosticInfoSSP>(DI));
+    return;
   default:
     // Plugin IDs are not bound to any value as they are set dynamically.
     ComputeDiagRemarkID(Severity, backend_plugin, DiagID);
Index: include/clang/Basic/DiagnosticGroups.td
===================================================================
--- include/clang/Basic/DiagnosticGroups.td
+++ include/clang/Basic/DiagnosticGroups.td
@@ -905,3 +905,7 @@
 // A warning group for warnings about code that clang accepts when
 // compiling OpenCL C/C++ but which is not compatible with the SPIR spec.
 def SpirCompat : DiagGroup<"spir-compat">;
+
+// A remark group for remarks about why stack protection was applied to a
+// function.
+def SSPReason : DiagGroup<"ssp-reason">;
Index: include/clang/Basic/DiagnosticFrontendKinds.td
===================================================================
--- include/clang/Basic/DiagnosticFrontendKinds.td
+++ include/clang/Basic/DiagnosticFrontendKinds.td
@@ -224,4 +224,11 @@
 
 def warn_option_invalid_ocl_version : Warning<
   "OpenCL version %0 does not support the option '%1'">, InGroup<Deprecated>;
+
+def remark_ssp_applied_reason
+    : Remark<"SSP applied to function due to %select{an unknown reason|a "
+             "call to alloca|a stack allocated buffer or struct containing a "
+             "buffer|the address of a local variable being taken|a function "
+             "attribute or use of -fstack-protector-all}0">,
+      InGroup<SSPReason>;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to