Fix bugs with default parameter values for pointer-typed function parameters.

In particular "void foo(int * ptr = NULL)" and the like work now.

Issue #197.
This commit is contained in:
Matt Pharr
2012-03-28 11:51:56 -07:00
parent b3c5043dcc
commit 540fc6c2f3
4 changed files with 24 additions and 22 deletions

View File

@@ -424,7 +424,7 @@ Declarator::GetType(const Type *base, DeclSpecs *ds) const {
case DK_FUNCTION: { case DK_FUNCTION: {
std::vector<const Type *> args; std::vector<const Type *> args;
std::vector<std::string> argNames; std::vector<std::string> argNames;
std::vector<ConstExpr *> argDefaults; std::vector<Expr *> argDefaults;
std::vector<SourcePos> argPos; std::vector<SourcePos> argPos;
// Loop over the function arguments and store the names, types, // Loop over the function arguments and store the names, types,
@@ -482,23 +482,25 @@ Declarator::GetType(const Type *base, DeclSpecs *ds) const {
argNames.push_back(sym->name); argNames.push_back(sym->name);
argPos.push_back(sym->pos); argPos.push_back(sym->pos);
ConstExpr *init = NULL; Expr *init = NULL;
if (d->declarators.size()) { if (d->declarators.size()) {
// Try to find an initializer expression; if there is one, // Try to find an initializer expression.
// it lives down to the base declarator.
Declarator *decl = d->declarators[0]; Declarator *decl = d->declarators[0];
while (decl->child != NULL) { while (decl->child != NULL) {
Assert(decl->initExpr == NULL); if (decl->initExpr != NULL) {
decl = decl->child; decl->initExpr = TypeCheck(decl->initExpr);
} decl->initExpr = Optimize(decl->initExpr);
if (decl->initExpr != NULL &&
if (decl->initExpr != NULL && ((init = dynamic_cast<ConstExpr *>(decl->initExpr)) == NULL) &&
(decl->initExpr = TypeCheck(decl->initExpr)) != NULL && ((init = dynamic_cast<NullPointerExpr *>(decl->initExpr)) == NULL)) {
(decl->initExpr = Optimize(decl->initExpr)) != NULL && Error(decl->initExpr->pos, "Default value for parameter "
(init = dynamic_cast<ConstExpr *>(decl->initExpr)) == NULL) { "\"%s\" must be a compile-time constant.",
Error(decl->initExpr->pos, "Default value for parameter " sym->name.c_str());
"\"%s\" must be a compile-time constant.", }
sym->name.c_str()); break;
}
else
decl = decl->child;
} }
} }
argDefaults.push_back(init); argDefaults.push_back(init);

View File

@@ -547,7 +547,7 @@ Module::AddFunctionDeclaration(Symbol *funSym, bool isInline) {
for (int i = 0; i < nArgs; ++i) { for (int i = 0; i < nArgs; ++i) {
const Type *argType = functionType->GetParameterType(i); const Type *argType = functionType->GetParameterType(i);
const std::string &argName = functionType->GetParameterName(i); const std::string &argName = functionType->GetParameterName(i);
ConstExpr *defaultValue = functionType->GetParameterDefault(i); Expr *defaultValue = functionType->GetParameterDefault(i);
const SourcePos &argPos = functionType->GetParameterSourcePos(i); const SourcePos &argPos = functionType->GetParameterSourcePos(i);
// If the function is exported, make sure that the parameter // If the function is exported, make sure that the parameter

View File

@@ -2330,7 +2330,7 @@ FunctionType::FunctionType(const Type *r, const std::vector<const Type *> &a,
SourcePos p) SourcePos p)
: isTask(false), isExported(false), isExternC(false), returnType(r), : isTask(false), isExported(false), isExternC(false), returnType(r),
paramTypes(a), paramNames(std::vector<std::string>(a.size(), "")), paramTypes(a), paramNames(std::vector<std::string>(a.size(), "")),
paramDefaults(std::vector<ConstExpr *>(a.size(), NULL)), paramDefaults(std::vector<Expr *>(a.size(), NULL)),
paramPositions(std::vector<SourcePos>(a.size(), p)) { paramPositions(std::vector<SourcePos>(a.size(), p)) {
Assert(returnType != NULL); Assert(returnType != NULL);
isSafe = false; isSafe = false;
@@ -2340,7 +2340,7 @@ FunctionType::FunctionType(const Type *r, const std::vector<const Type *> &a,
FunctionType::FunctionType(const Type *r, const std::vector<const Type *> &a, FunctionType::FunctionType(const Type *r, const std::vector<const Type *> &a,
const std::vector<std::string> &an, const std::vector<std::string> &an,
const std::vector<ConstExpr *> &ad, const std::vector<Expr *> &ad,
const std::vector<SourcePos> &ap, const std::vector<SourcePos> &ap,
bool it, bool is, bool ec) bool it, bool is, bool ec)
: isTask(it), isExported(is), isExternC(ec), returnType(r), paramTypes(a), : isTask(it), isExported(is), isExternC(ec), returnType(r), paramTypes(a),
@@ -2614,7 +2614,7 @@ FunctionType::GetParameterType(int i) const {
} }
ConstExpr * Expr *
FunctionType::GetParameterDefault(int i) const { FunctionType::GetParameterDefault(int i) const {
Assert(i < (int)paramDefaults.size()); Assert(i < (int)paramDefaults.size());
return paramDefaults[i]; return paramDefaults[i];

6
type.h
View File

@@ -745,7 +745,7 @@ public:
FunctionType(const Type *returnType, FunctionType(const Type *returnType,
const std::vector<const Type *> &argTypes, const std::vector<const Type *> &argTypes,
const std::vector<std::string> &argNames, const std::vector<std::string> &argNames,
const std::vector<ConstExpr *> &argDefaults, const std::vector<Expr *> &argDefaults,
const std::vector<SourcePos> &argPos, const std::vector<SourcePos> &argPos,
bool isTask, bool isExported, bool isExternC); bool isTask, bool isExported, bool isExternC);
@@ -785,7 +785,7 @@ public:
int GetNumParameters() const { return (int)paramTypes.size(); } int GetNumParameters() const { return (int)paramTypes.size(); }
const Type *GetParameterType(int i) const; const Type *GetParameterType(int i) const;
ConstExpr * GetParameterDefault(int i) const; Expr * GetParameterDefault(int i) const;
const SourcePos &GetParameterSourcePos(int i) const; const SourcePos &GetParameterSourcePos(int i) const;
const std::string &GetParameterName(int i) const; const std::string &GetParameterName(int i) const;
@@ -818,7 +818,7 @@ private:
const std::vector<std::string> paramNames; const std::vector<std::string> paramNames;
/** Default values of the function's arguments. For arguments without /** Default values of the function's arguments. For arguments without
default values provided, NULL is stored. */ default values provided, NULL is stored. */
mutable std::vector<ConstExpr *> paramDefaults; mutable std::vector<Expr *> paramDefaults;
/** The names provided (if any) with the function arguments in the /** The names provided (if any) with the function arguments in the
function's signature. These should only be used for error messages function's signature. These should only be used for error messages
and the like and so not affect testing function types for equality, and the like and so not affect testing function types for equality,