[PATCH] Make sure CallExpr::getLocStart doesn't segfault

Keno Fischer kfischer at college.harvard.edu
Thu Aug 14 16:14:34 PDT 2014


Hi rnk,

When the CallExpr passed to Sema::ConvertArgumentsForCall has all default parameters, and the number of actual arguments passed is zero, this function will segfault in the call to Call->getLocStart() if the Callee has an invalid getLocStart(), the reason being that since ConvertArgumentsForCall has set the correct number of arguments, but has not filled them in yet, getLocStart() will try to access the first (not yet existent) argument and thus segfaults. 

This fixes that by making getLocStart return an invalid source location if the queried argument is NULL rather than segfaulting.

http://reviews.llvm.org/D4917

Files:
  include/clang/AST/Expr.h
  lib/AST/Expr.cpp

Index: include/clang/AST/Expr.h
===================================================================
--- include/clang/AST/Expr.h
+++ include/clang/AST/Expr.h
@@ -2212,11 +2212,11 @@
   /// getArg - Return the specified argument.
   Expr *getArg(unsigned Arg) {
     assert(Arg < NumArgs && "Arg access out of range!");
-    return cast<Expr>(SubExprs[Arg+getNumPreArgs()+PREARGS_START]);
+    return cast_or_null<Expr>(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
   }
   const Expr *getArg(unsigned Arg) const {
     assert(Arg < NumArgs && "Arg access out of range!");
-    return cast<Expr>(SubExprs[Arg+getNumPreArgs()+PREARGS_START]);
+    return cast_or_null<Expr>(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
   }
 
   /// setArg - Set the specified argument.
Index: lib/AST/Expr.cpp
===================================================================
--- lib/AST/Expr.cpp
+++ lib/AST/Expr.cpp
@@ -1252,16 +1252,17 @@
     return cast<CXXOperatorCallExpr>(this)->getLocStart();
 
   SourceLocation begin = getCallee()->getLocStart();
-  if (begin.isInvalid() && getNumArgs() > 0)
+  if (begin.isInvalid() && getNumArgs() > 0 && getArg(0) != nullptr)
     begin = getArg(0)->getLocStart();
   return begin;
 }
 SourceLocation CallExpr::getLocEnd() const {
   if (isa<CXXOperatorCallExpr>(this))
     return cast<CXXOperatorCallExpr>(this)->getLocEnd();
 
   SourceLocation end = getRParenLoc();
-  if (end.isInvalid() && getNumArgs() > 0)
+  if (end.isInvalid() && getNumArgs() > 0 &&
+      getArg(getNumArgs() - 1) != nullptr)
     end = getArg(getNumArgs() - 1)->getLocEnd();
   return end;
 }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D4917.12528.patch
Type: text/x-patch
Size: 1613 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140814/2813c048/attachment.bin>


More information about the cfe-commits mailing list