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;
}
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;
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits