[compiler-rt] r297748 - [ubsan] Add diagnostic handlers for nullability errors

Vedant Kumar via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 14 09:32:27 PDT 2017


Author: vedantk
Date: Tue Mar 14 11:32:27 2017
New Revision: 297748

URL: http://llvm.org/viewvc/llvm-project?rev=297748&view=rev
Log:
[ubsan] Add diagnostic handlers for nullability errors

Add 'nullability_arg' and 'nullability_return' diagnostic handlers, and
also add a TypeCheckKind for null assignments to _Nonnull. With this in
place, we can update clang to use the nicer handlers for nullability
diagnostics.

The alternative to this approach is to update the existing 'nonnull_arg'
and 'nonnull_return' handlers to accept a boolean parameter. However,
versioning the existing handlers would cause code size bloat, and the
complexity cost of introducing new handlers into the runtime is low.

I will add tests for this, and all of -fsanitize=nullability, into
check-ubsan once the clang side of the changes is in.

Modified:
    compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc
    compiler-rt/trunk/lib/ubsan/ubsan_handlers.h

Modified: compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc?rev=297748&r1=297747&r2=297748&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc Tue Mar 14 11:32:27 2017
@@ -38,7 +38,7 @@ bool ignoreReport(SourceLocation SLoc, R
 const char *TypeCheckKinds[] = {
     "load of", "store to", "reference binding to", "member access within",
     "member call on", "constructor call on", "downcast of", "downcast of",
-    "upcast of", "cast to virtual base of"};
+    "upcast of", "cast to virtual base of", "_Nonnull binding to"};
 }
 
 static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer,
@@ -472,7 +472,8 @@ void __ubsan::__ubsan_handle_function_ty
   Die();
 }
 
-static void handleNonNullReturn(NonNullReturnData *Data, ReportOptions Opts) {
+static void handleNonNullReturn(NonNullReturnData *Data, ReportOptions Opts,
+                                bool IsAttr) {
   SourceLocation Loc = Data->Loc.acquire();
   ErrorType ET = ErrorType::InvalidNullReturn;
 
@@ -484,21 +485,35 @@ static void handleNonNullReturn(NonNullR
   Diag(Loc, DL_Error, "null pointer returned from function declared to never "
                       "return null");
   if (!Data->AttrLoc.isInvalid())
-    Diag(Data->AttrLoc, DL_Note, "returns_nonnull attribute specified here");
+    Diag(Data->AttrLoc, DL_Note, "%0 specified here")
+        << (IsAttr ? "returns_nonnull attribute"
+                   : "_Nonnull return type annotation");
 }
 
 void __ubsan::__ubsan_handle_nonnull_return(NonNullReturnData *Data) {
   GET_REPORT_OPTIONS(false);
-  handleNonNullReturn(Data, Opts);
+  handleNonNullReturn(Data, Opts, true);
 }
 
 void __ubsan::__ubsan_handle_nonnull_return_abort(NonNullReturnData *Data) {
   GET_REPORT_OPTIONS(true);
-  handleNonNullReturn(Data, Opts);
+  handleNonNullReturn(Data, Opts, true);
   Die();
 }
 
-static void handleNonNullArg(NonNullArgData *Data, ReportOptions Opts) {
+void __ubsan::__ubsan_handle_nullability_return(NonNullReturnData *Data) {
+  GET_REPORT_OPTIONS(false);
+  handleNonNullReturn(Data, Opts, false);
+}
+
+void __ubsan::__ubsan_handle_nullability_return_abort(NonNullReturnData *Data) {
+  GET_REPORT_OPTIONS(true);
+  handleNonNullReturn(Data, Opts, false);
+  Die();
+}
+
+static void handleNonNullArg(NonNullArgData *Data, ReportOptions Opts,
+                             bool IsAttr) {
   SourceLocation Loc = Data->Loc.acquire();
   ErrorType ET = ErrorType::InvalidNullArgument;
 
@@ -507,20 +522,34 @@ static void handleNonNullArg(NonNullArgD
 
   ScopedReport R(Opts, Loc, ET);
 
-  Diag(Loc, DL_Error, "null pointer passed as argument %0, which is declared to "
-       "never be null") << Data->ArgIndex;
+  Diag(Loc, DL_Error,
+       "null pointer passed as argument %0, which is declared to "
+       "never be null")
+      << Data->ArgIndex;
   if (!Data->AttrLoc.isInvalid())
-    Diag(Data->AttrLoc, DL_Note, "nonnull attribute specified here");
+    Diag(Data->AttrLoc, DL_Note, "%0 specified here")
+        << (IsAttr ? "nonnull attribute" : "_Nonnull type annotation");
 }
 
 void __ubsan::__ubsan_handle_nonnull_arg(NonNullArgData *Data) {
   GET_REPORT_OPTIONS(false);
-  handleNonNullArg(Data, Opts);
+  handleNonNullArg(Data, Opts, true);
 }
 
 void __ubsan::__ubsan_handle_nonnull_arg_abort(NonNullArgData *Data) {
   GET_REPORT_OPTIONS(true);
-  handleNonNullArg(Data, Opts);
+  handleNonNullArg(Data, Opts, true);
+  Die();
+}
+
+void __ubsan::__ubsan_handle_nullability_arg(NonNullArgData *Data) {
+  GET_REPORT_OPTIONS(false);
+  handleNonNullArg(Data, Opts, false);
+}
+
+void __ubsan::__ubsan_handle_nullability_arg_abort(NonNullArgData *Data) {
+  GET_REPORT_OPTIONS(true);
+  handleNonNullArg(Data, Opts, false);
   Die();
 }
 

Modified: compiler-rt/trunk/lib/ubsan/ubsan_handlers.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_handlers.h?rev=297748&r1=297747&r2=297748&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers.h (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers.h Tue Mar 14 11:32:27 2017
@@ -136,8 +136,10 @@ struct NonNullReturnData {
   SourceLocation AttrLoc;
 };
 
-/// \brief Handle returning null from function with returns_nonnull attribute.
+/// \brief Handle returning null from function with the returns_nonnull
+/// attribute, or a return type annotated with _Nonnull.
 RECOVERABLE(nonnull_return, NonNullReturnData *Data)
+RECOVERABLE(nullability_return, NonNullReturnData *Data)
 
 struct NonNullArgData {
   SourceLocation Loc;
@@ -145,8 +147,10 @@ struct NonNullArgData {
   int ArgIndex;
 };
 
-/// \brief Handle passing null pointer to function with nonnull attribute.
+/// \brief Handle passing null pointer to a function parameter with the nonnull
+/// attribute, or a _Nonnull type annotation.
 RECOVERABLE(nonnull_arg, NonNullArgData *Data)
+RECOVERABLE(nullability_arg, NonNullArgData *Data)
 
 /// \brief Known CFI check kinds.
 /// Keep in sync with the enum of the same name in CodeGenFunction.h




More information about the llvm-commits mailing list