From 540fc6c2f3eadf427e817a80360886027cff9759 Mon Sep 17 00:00:00 2001 From: Matt Pharr Date: Wed, 28 Mar 2012 11:51:56 -0700 Subject: [PATCH] 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. --- decl.cpp | 32 +++++++++++++++++--------------- module.cpp | 2 +- type.cpp | 6 +++--- type.h | 6 +++--- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/decl.cpp b/decl.cpp index 748cffb1..c54abdb9 100644 --- a/decl.cpp +++ b/decl.cpp @@ -424,7 +424,7 @@ Declarator::GetType(const Type *base, DeclSpecs *ds) const { case DK_FUNCTION: { std::vector args; std::vector argNames; - std::vector argDefaults; + std::vector argDefaults; std::vector argPos; // 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); argPos.push_back(sym->pos); - ConstExpr *init = NULL; + Expr *init = NULL; if (d->declarators.size()) { - // Try to find an initializer expression; if there is one, - // it lives down to the base declarator. + // Try to find an initializer expression. Declarator *decl = d->declarators[0]; while (decl->child != NULL) { - Assert(decl->initExpr == NULL); - decl = decl->child; - } - - if (decl->initExpr != NULL && - (decl->initExpr = TypeCheck(decl->initExpr)) != NULL && - (decl->initExpr = Optimize(decl->initExpr)) != NULL && - (init = dynamic_cast(decl->initExpr)) == NULL) { - Error(decl->initExpr->pos, "Default value for parameter " - "\"%s\" must be a compile-time constant.", - sym->name.c_str()); + if (decl->initExpr != NULL) { + decl->initExpr = TypeCheck(decl->initExpr); + decl->initExpr = Optimize(decl->initExpr); + if (decl->initExpr != NULL && + ((init = dynamic_cast(decl->initExpr)) == NULL) && + ((init = dynamic_cast(decl->initExpr)) == NULL)) { + Error(decl->initExpr->pos, "Default value for parameter " + "\"%s\" must be a compile-time constant.", + sym->name.c_str()); + } + break; + } + else + decl = decl->child; } } argDefaults.push_back(init); diff --git a/module.cpp b/module.cpp index 4555a3d5..3f184a42 100644 --- a/module.cpp +++ b/module.cpp @@ -547,7 +547,7 @@ Module::AddFunctionDeclaration(Symbol *funSym, bool isInline) { for (int i = 0; i < nArgs; ++i) { const Type *argType = functionType->GetParameterType(i); const std::string &argName = functionType->GetParameterName(i); - ConstExpr *defaultValue = functionType->GetParameterDefault(i); + Expr *defaultValue = functionType->GetParameterDefault(i); const SourcePos &argPos = functionType->GetParameterSourcePos(i); // If the function is exported, make sure that the parameter diff --git a/type.cpp b/type.cpp index 06ab8bd2..80856d5e 100644 --- a/type.cpp +++ b/type.cpp @@ -2330,7 +2330,7 @@ FunctionType::FunctionType(const Type *r, const std::vector &a, SourcePos p) : isTask(false), isExported(false), isExternC(false), returnType(r), paramTypes(a), paramNames(std::vector(a.size(), "")), - paramDefaults(std::vector(a.size(), NULL)), + paramDefaults(std::vector(a.size(), NULL)), paramPositions(std::vector(a.size(), p)) { Assert(returnType != NULL); isSafe = false; @@ -2340,7 +2340,7 @@ FunctionType::FunctionType(const Type *r, const std::vector &a, FunctionType::FunctionType(const Type *r, const std::vector &a, const std::vector &an, - const std::vector &ad, + const std::vector &ad, const std::vector &ap, bool it, bool is, bool ec) : 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 { Assert(i < (int)paramDefaults.size()); return paramDefaults[i]; diff --git a/type.h b/type.h index 94c28f0b..54cea005 100644 --- a/type.h +++ b/type.h @@ -745,7 +745,7 @@ public: FunctionType(const Type *returnType, const std::vector &argTypes, const std::vector &argNames, - const std::vector &argDefaults, + const std::vector &argDefaults, const std::vector &argPos, bool isTask, bool isExported, bool isExternC); @@ -785,7 +785,7 @@ public: int GetNumParameters() const { return (int)paramTypes.size(); } const Type *GetParameterType(int i) const; - ConstExpr * GetParameterDefault(int i) const; + Expr * GetParameterDefault(int i) const; const SourcePos &GetParameterSourcePos(int i) const; const std::string &GetParameterName(int i) const; @@ -818,7 +818,7 @@ private: const std::vector paramNames; /** Default values of the function's arguments. For arguments without default values provided, NULL is stored. */ - mutable std::vector paramDefaults; + mutable std::vector paramDefaults; /** The names provided (if any) with the function arguments in the function's signature. These should only be used for error messages and the like and so not affect testing function types for equality,