]> granicus.if.org Git - clang/commitdiff
Make sure CallExpr::getLocStart doesn't segfault
authorKeno Fischer <kfischer@college.harvard.edu>
Fri, 15 Aug 2014 01:39:12 +0000 (01:39 +0000)
committerKeno Fischer <kfischer@college.harvard.edu>
Fri, 15 Aug 2014 01:39:12 +0000 (01:39 +0000)
Summary:
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.

Reviewers: rnk

Reviewed By: rnk

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D4917

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@215686 91177308-0d34-0410-b5e6-96231b3b80d8

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

index b4bb0b6b64408ad266d99cf0c26e5cd285af5654..4b77028a9125880bf51fd644c7135ae323237a53 100644 (file)
@@ -2212,11 +2212,11 @@ public:
   /// 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 97f1b8826193909e41889380c01776cfae92dd3c..e1ebda245f2b8edf96ce7b61d35ec976a87157fe 100644 (file)
@@ -1252,7 +1252,7 @@ SourceLocation CallExpr::getLocStart() const {
     return cast<CXXOperatorCallExpr>(this)->getLocStart();
 
   SourceLocation begin = getCallee()->getLocStart();
-  if (begin.isInvalid() && getNumArgs() > 0)
+  if (begin.isInvalid() && getNumArgs() > 0 && getArg(0))
     begin = getArg(0)->getLocStart();
   return begin;
 }
@@ -1261,7 +1261,7 @@ SourceLocation CallExpr::getLocEnd() const {
     return cast<CXXOperatorCallExpr>(this)->getLocEnd();
 
   SourceLocation end = getRParenLoc();
-  if (end.isInvalid() && getNumArgs() > 0)
+  if (end.isInvalid() && getNumArgs() > 0 && getArg(getNumArgs() - 1))
     end = getArg(getNumArgs() - 1)->getLocEnd();
   return end;
 }