From 8444ae7cfeaefae031f8fedf0d1435ca3b14d90b Mon Sep 17 00:00:00 2001
From: Keno Fischer <kfischer@college.harvard.edu>
Date: Fri, 15 Aug 2014 01:39:12 +0000
Subject: [PATCH] Make sure CallExpr::getLocStart doesn't segfault

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 | 4 ++--
 lib/AST/Expr.cpp         | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index b4bb0b6b644..4b77028a912 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -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.
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 97f1b882619..e1ebda245f2 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -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;
 }
-- 
GitLab