@@ -68,9 +68,10 @@ fn void Analyser.analyseFunction(Analyser* ma, FunctionDecl* fd) {
6868 VarDecl** params = fd.getParams();
6969 u32 auto_arg_count = 0;
7070 u32 first_auto_arg = 0;
71+ bool has_default = false;
7172 for (u32 i=0; i<num_params; i++) {
72- VarDecl* v = params[i];
73- TypeRef* ref = v .getTypeRef();
73+ VarDecl* vd = params[i];
74+ TypeRef* ref = vd .getTypeRef();
7475
7576 QualType res = ma.analyseTypeRef(ref);
7677 if (res.isInvalid()) continue;
@@ -88,31 +89,48 @@ fn void Analyser.analyseFunction(Analyser* ma, FunctionDecl* fd) {
8889
8990 if (is_public) setTypePublicUsed(res);
9091
91- if (v.hasAutoAttr()) {
92+ if (vd.hasInit()) {
93+ has_default = true;
94+ if (vd.hasAutoAttr()) {
95+ ma.error(vd.getAssignLoc(), "automatic argument cannot have default value");
96+ }
97+ if (vd.hasPrintfFormat()) {
98+ ma.error(vd.getAssignLoc(), "printf_format parameter cannot have default value");
99+ }
100+ Expr** initExpr = vd.getInit2();
101+ ma.analyseInitExpr(initExpr, res, vd.getAssignLoc(), false, true);
102+ } else {
103+ if (has_default) {
104+ Decl* d = (Decl*)vd;
105+ ma.error(d.getLoc(), "parameter must have a default value");
106+ }
107+ }
108+
109+ if (vd.hasAutoAttr()) {
92110 if (auto_arg_count == 0) first_auto_arg = i;
93111 auto_arg_count++;
94112 if (auto_arg_count > 3) {
95113 ma.error(ref.getLoc(), "too many automatic arguments");
96114 }
97115 // check type
98- if (v .hasAttrAutoFile() && !ref.isConstCharPtr()) { // check for 'const char *'
116+ if (vd .hasAttrAutoFile() && !ref.isConstCharPtr()) { // check for 'const char *'
99117 ma.error(ref.getLoc(), "attribute 'auto_file' requires a parameter of type 'const char*'");
100118 }
101- if (v .hasAttrAutoLine() && !ref.isU32()) { // check for 'u32'
119+ if (vd .hasAttrAutoLine() && !ref.isU32()) { // check for 'u32'
102120 ma.error(ref.getLoc(), "attribute 'auto_line' requires a parameter of type 'u32'");
103121 }
104- if (v .hasAttrAutoFunc() && !ref.isConstCharPtr()) { // check for 'const char *'
122+ if (vd .hasAttrAutoFunc() && !ref.isConstCharPtr()) { // check for 'const char *'
105123 ma.error(ref.getLoc(), "attribute 'auto_func' requires a parameter of type 'const char*'");
106124 }
107125 }
108126
109- if (v .hasPrintfFormat()) {
110- ma.checkPrintfFormat(v , res, i, fd);
127+ if (vd .hasPrintfFormat()) {
128+ ma.checkPrintfFormat(vd , res, i, fd);
111129 fd.setAttrPrintf((u8)i + 1); // change to 1-based
112130 }
113131
114132 // Note: we dont check the arg name for clash here, but when checking body
115- Decl* d = (Decl*)v ;
133+ Decl* d = (Decl*)vd ;
116134 d.setType(res);
117135 d.setChecked();
118136 }
@@ -213,7 +231,6 @@ fn void Analyser.analyseFunctionBody(Analyser* ma, FunctionDecl* fd, scope.Scope
213231
214232 ma.scope.reset();
215233 ma.scope.enter(scope.Function | scope.Decl);
216- bool has_default = false;
217234 u32 num_params = fd.getNumParams();
218235 VarDecl** params = fd.getParams();
219236 for (u32 i=0; i<num_params; i++) {
@@ -222,27 +239,6 @@ fn void Analyser.analyseFunctionBody(Analyser* ma, FunctionDecl* fd, scope.Scope
222239 bool error = ma.scope.add(p);
223240 if (error) return; // no need to set ma.has_error. NOTE: pushCheck remains!
224241 }
225- VarDecl* vd = (VarDecl*)p;
226- if (vd.hasInit()) {
227- has_default = true;
228- if (vd.hasAutoAttr()) {
229- ma.error(vd.getAssignLoc(), "automatic argument cannot have default value");
230- }
231- if (vd.hasPrintfFormat()) {
232- ma.error(vd.getAssignLoc(), "printf_format parameter cannot have default value");
233- }
234- Expr** initExpr = vd.getInit2();
235- if (ma.analyseInitExpr(initExpr, p.getType(), vd.getAssignLoc(), false)) {
236- Expr* e = vd.getInit();
237- if (!e.isCtc() && !e.isCtv()) {
238- ma.errorRange(e.getLoc(), e.getRange(), "default parameter value is not a compile-time value");
239- }
240- }
241- } else {
242- if (has_default) {
243- ma.error(p.getLoc(), "parameter must have a default value");
244- }
245- }
246242 }
247243
248244 ma.has_error = false;
0 commit comments