[tor-commits] [trunnel/master] Suppress deadcode warnings from static analysis tools

nickm at torproject.org nickm at torproject.org
Fri Sep 26 13:30:32 UTC 2014


commit 3ddd61e0f7fc81e8067c5ca10eda6c832055b963
Author: Nick Mathewson <nickm at torproject.org>
Date:   Fri Sep 26 09:28:10 2014 -0400

    Suppress deadcode warnings from static analysis tools
    
    It's intentional that trunnel will generate some dead checks: I
    deliberately wrote it to _always_ check how many bytes are
    remaining, even if the check might be dead.  The alternative would
    be to make the code more complex in order to teach it how to
    sometimes omit checks... but such complexity would run the risk of
    accidentally omitting a necessary check.
    
    So replace the "if (remaining < foo) goto bar;" checks with a macro,
    and use an #ifdef to define the macro such that the static tool
    (probably) won't conclude that check can never be true.
---
 lib/trunnel/CodeGen.py |   32 +++++++++++++++++++++++---------
 1 file changed, 23 insertions(+), 9 deletions(-)

diff --git a/lib/trunnel/CodeGen.py b/lib/trunnel/CodeGen.py
index 392783b..9b07e2f 100644
--- a/lib/trunnel/CodeGen.py
+++ b/lib/trunnel/CodeGen.py
@@ -2406,8 +2406,7 @@ class ParseFnGenerator(CodeGenerator):
         ntoh = NTOH_FN[width]
         self.needLabels.add(self.truncatedLabel)
         self.format("""
-                if (remaining < {nbytes})
-                  goto {truncated};
+                CHECK_REMAINING({nbytes}, {truncated});
                 {element} = {ntoh}(trunnel_get_uint{width}(ptr));
                 remaining -= {nbytes}; ptr += {nbytes};
                 """, nbytes=nbytes, truncated=self.truncatedLabel,
@@ -2463,8 +2462,7 @@ class ParseFnGenerator(CodeGenerator):
                 if bytesPerElt > 1:
                     multiplier = "%s * " % bytesPerElt
             self.format("""
-                        if (remaining < ({multiplier}{width}))
-                          goto {truncated};
+                        CHECK_REMAINING({multiplier}{width}, {truncated});
                         memcpy(obj->{c_name}, ptr, {multiplier}{width});
                         """, c_name=sfa.c_name, multiplier=multiplier,
                         width=sfa.width, truncated=self.truncatedLabel)
@@ -2523,7 +2521,7 @@ class ParseFnGenerator(CodeGenerator):
         # FFFF some of this is kinda cut-and-paste
         if arrayIsBytes(sva):
             if sva.widthfield != None:
-                self.w('if (remaining < %s)\n  goto %s;\n' % (
+                self.w('CHECK_REMAINING(%s, %s);\n' % (
                     w, self.truncatedLabel))
             else:
                 w = "remaining"
@@ -2643,8 +2641,7 @@ class ParseFnGenerator(CodeGenerator):
             self.format("""
                     {{
                       size_t remaining_after;
-                      if ({field} > remaining)
-                         goto {truncated};
+                      CHECK_REMAINING({field}, {truncated});
                       remaining_after = remaining - {field};
                       remaining = {field};
                     """, field=field_, truncated=self.truncatedLabel)
@@ -2652,8 +2649,7 @@ class ParseFnGenerator(CodeGenerator):
             self.format("""
                     {{
                       size_t remaining_after;
-                      if (remaining < {leftafter})
-                         goto {truncated};
+                      CHECK_REMAINING({leftafter}, {truncated});
                       remaining_after = {leftafter};
                       remaining = remaining - {leftafter};
                     """, leftafter=sml.leftoverbytes,
@@ -2748,6 +2744,22 @@ MODULE_BOILERPLATE = """\
     (obj)->trunnel_error_code_ = 1; \\
   } while (0)
 
+#if defined(__COVERITY__) || defined(__clang_analyzer__)
+/* If we're runnning a static analysis tool, we don't want it to complain
+ * that some of our remaining-bytes checks are dead-code. */
+int %(csafe_fname)s_deadcode_dummy__ = 0;
+#define OR_DEADCODE_DUMMY || %(csafe_fname)s_deadcode_dummy__
+#else
+#define OR_DEADCODE_DUMMY
+#endif
+
+#define CHECK_REMAINING(nbytes, label)                           \\
+  do {                                                           \\
+    if (remaining < (nbytes) OR_DEADCODE_DUMMY) {                \\
+      goto label;                                                \\
+    }                                                            \\
+  } while (0)
+
 """
 
 
@@ -2765,6 +2777,7 @@ def generate_code(input_fname, extra_options=[], target_dir=None):
 
     c_fname = basename + ".c"
     h_fname = basename + ".h"
+    csafe_fname = re.sub(r'[^a-zA-Z]', '', os.path.split(basename)[1])
 
     inp = open(input_fname, 'r')
     t = trunnel.Grammar.Lexer().tokenize(inp.read())
@@ -2787,6 +2800,7 @@ def generate_code(input_fname, extra_options=[], target_dir=None):
         'guard_macro': guard_macro,
         'h_fname': os.path.split(h_fname)[1],
         'c_fname': os.path.split(c_fname)[1],
+        'csafe_fname' : csafe_fname,
         'expose_definitions': "".join(expose_definitions),
         'version' : trunnel.__version__
     }



More information about the tor-commits mailing list