1 
2 /* Compiler implementation of the D programming language
3  * Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
4  * written by Walter Bright
5  * http://www.digitalmars.com
6  * Distributed under the Boost Software License, Version 1.0.
7  * http://www.boost.org/LICENSE_1_0.txt
8  */
9 
10 #include "dsymbol.h"
11 #include "aggregate.h"
12 #include "attrib.h"
13 #include "declaration.h"
14 #include "errors.h"
15 #include "id.h"
16 #include "init.h"
17 #include "module.h"
18 #include "nspace.h"
19 #include "scope.h"
20 #include "statement.h"
21 #include "statement_rewrite_walker.h"
22 #include "target.h"
23 #include "template.h"
24 #include "visitor.h"
25 
26 bool allowsContractWithoutBody(FuncDeclaration *funcdecl);
27 int blockExit(Statement *s, FuncDeclaration *func, bool mustNotThrow);
28 bool checkReturnEscape(Scope *sc, Expression *e, bool gag);
29 bool checkReturnEscapeRef(Scope *sc, Expression *e, bool gag);
30 TypeIdentifier *getThrowable();
31 char *MODtoChars(MOD mod);
32 Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads);
33 void allocFieldinit(Scope *sc, size_t dim);
34 void freeFieldinit(Scope *sc);
35 
36 /* Determine if function should add `return 0;`
37  */
addReturn0(FuncDeclaration * funcdecl)38 static bool addReturn0(FuncDeclaration *funcdecl)
39 {
40     TypeFunction *f = (TypeFunction *)funcdecl->type;
41 
42     return f->next->ty == Tvoid &&
43         (funcdecl->isMain() || (global.params.betterC && funcdecl->isCMain()));
44 }
45 
46 /********************************************************
47  * Generate Expression to call the invariant.
48  * Input:
49  *      ad      aggregate with the invariant
50  *      vthis   variable with 'this'
51  * Returns:
52  *      void expression that calls the invariant
53  */
addInvariant(AggregateDeclaration * ad,VarDeclaration * vthis)54 static Expression *addInvariant(AggregateDeclaration *ad, VarDeclaration *vthis)
55 {
56     Expression *e = NULL;
57 
58     // Call invariant directly only if it exists
59     FuncDeclaration *inv = ad->inv;
60     ClassDeclaration *cd = ad->isClassDeclaration();
61 
62     while (!inv && cd)
63     {
64         cd = cd->baseClass;
65         if (!cd)
66             break;
67         inv = cd->inv;
68     }
69     if (inv)
70     {
71     #if 1
72         // Workaround for bugzilla 13394: For the correct mangling,
73         // run attribute inference on inv if needed.
74         inv->functionSemantic();
75     #endif
76 
77         //e = new DsymbolExp(Loc(), inv);
78         //e = new CallExp(Loc(), e);
79         //dsymbolSemantic(e, sc2);
80 
81         /* https://issues.dlang.org/show_bug.cgi?id=13113
82          * Currently virtual invariant calls completely
83          * bypass attribute enforcement.
84          * Change the behavior of pre-invariant call by following it.
85          */
86         e = new ThisExp(Loc());
87         e->type = vthis->type;
88         e = new DotVarExp(Loc(), e, inv, false);
89         e->type = inv->type;
90         e = new CallExp(Loc(), e);
91         e->type = Type::tvoid;
92     }
93     return e;
94 }
95 
96 /* Tweak all return statements and dtor call for nrvo_var, for correct NRVO.
97  */
98 class NrvoWalker : public StatementRewriteWalker
99 {
100 public:
101     FuncDeclaration *fd;
102     Scope *sc;
103 
visit(ReturnStatement * s)104     void visit(ReturnStatement *s)
105     {
106         // See if all returns are instead to be replaced with a goto returnLabel;
107         if (fd->returnLabel)
108         {
109             /* Rewrite:
110              *  return exp;
111              * as:
112              *  vresult = exp; goto Lresult;
113              */
114             GotoStatement *gs = new GotoStatement(s->loc, Id::returnLabel);
115             gs->label = fd->returnLabel;
116 
117             Statement *s1 = gs;
118             if (s->exp)
119                 s1 = new CompoundStatement(s->loc, new ExpStatement(s->loc, s->exp), gs);
120 
121             replaceCurrent(s1);
122         }
123     }
visit(TryFinallyStatement * s)124     void visit(TryFinallyStatement *s)
125     {
126         DtorExpStatement *des;
127         if (fd->nrvo_can &&
128             s->finalbody && (des = s->finalbody->isDtorExpStatement()) != NULL &&
129             fd->nrvo_var == des->var)
130         {
131             if (!(global.params.useExceptions && ClassDeclaration::throwable))
132             {
133                 /* Don't need to call destructor at all, since it is nrvo
134                  */
135                 replaceCurrent(s->_body);
136                 s->_body->accept(this);
137                 return;
138             }
139 
140             /* Normally local variable dtors are called regardless exceptions.
141              * But for nrvo_var, its dtor should be called only when exception is thrown.
142              *
143              * Rewrite:
144              *      try { s->body; } finally { nrvo_var->edtor; }
145              *      // equivalent with:
146              *      //    s->body; scope(exit) nrvo_var->edtor;
147              * as:
148              *      try { s->body; } catch(Throwable __o) { nrvo_var->edtor; throw __o; }
149              *      // equivalent with:
150              *      //    s->body; scope(failure) nrvo_var->edtor;
151              */
152             Statement *sexception = new DtorExpStatement(Loc(), fd->nrvo_var->edtor, fd->nrvo_var);
153             Identifier *id = Identifier::generateId("__o");
154 
155             Statement *handler = new PeelStatement(sexception);
156             if (blockExit(sexception, fd, false) & BEfallthru)
157             {
158                 ThrowStatement *ts = new ThrowStatement(Loc(), new IdentifierExp(Loc(), id));
159                 ts->internalThrow = true;
160                 handler = new CompoundStatement(Loc(), handler, ts);
161             }
162 
163             Catches *catches = new Catches();
164             Catch *ctch = new Catch(Loc(), getThrowable(), id, handler);
165             ctch->internalCatch = true;
166             catchSemantic(ctch, sc);     // Run semantic to resolve identifier '__o'
167             catches->push(ctch);
168 
169             Statement *s2 = new TryCatchStatement(Loc(), s->_body, catches);
170             replaceCurrent(s2);
171             s2->accept(this);
172         }
173         else
174             StatementRewriteWalker::visit(s);
175     }
176 };
177 
178 class Semantic3Visitor : public Visitor
179 {
180 public:
181     Scope *sc;
182 
Semantic3Visitor(Scope * sc)183     Semantic3Visitor(Scope *sc)
184     {
185         this->sc = sc;
186     }
187 
visit(Dsymbol *)188     void visit(Dsymbol *)
189     {
190         // Most Dsymbols have no further semantic analysis needed
191     }
192 
visit(TemplateInstance * tempinst)193     void visit(TemplateInstance *tempinst)
194     {
195         //if (tempinst->toChars()[0] == 'D') *(char*)0=0;
196         if (tempinst->semanticRun >= PASSsemantic3)
197             return;
198         tempinst->semanticRun = PASSsemantic3;
199         if (!tempinst->errors && tempinst->members)
200         {
201             TemplateDeclaration *tempdecl = tempinst->tempdecl->isTemplateDeclaration();
202             assert(tempdecl);
203 
204             sc = tempdecl->_scope;
205             sc = sc->push(tempinst->argsym);
206             sc = sc->push(tempinst);
207             sc->tinst = tempinst;
208             sc->minst = tempinst->minst;
209 
210             int needGagging = (tempinst->gagged && !global.gag);
211             unsigned int olderrors = global.errors;
212             int oldGaggedErrors = -1;       // dead-store to prevent spurious warning
213             /* If this is a gagged instantiation, gag errors.
214              * Future optimisation: If the results are actually needed, errors
215              * would already be gagged, so we don't really need to run semantic
216              * on the members.
217              */
218             if (needGagging)
219                 oldGaggedErrors = global.startGagging();
220 
221             for (size_t i = 0; i < tempinst->members->length; i++)
222             {
223                 Dsymbol *s = (*tempinst->members)[i];
224                 semantic3(s, sc);
225                 if (tempinst->gagged && global.errors != olderrors)
226                     break;
227             }
228 
229             if (global.errors != olderrors)
230             {
231                 if (!tempinst->errors)
232                 {
233                     if (!tempdecl->literal)
234                         tempinst->error(tempinst->loc, "error instantiating");
235                     if (tempinst->tinst)
236                         tempinst->tinst->printInstantiationTrace();
237                 }
238                 tempinst->errors = true;
239             }
240             if (needGagging)
241                 global.endGagging(oldGaggedErrors);
242 
243             sc = sc->pop();
244             sc->pop();
245         }
246     }
247 
visit(TemplateMixin * tmix)248     void visit(TemplateMixin *tmix)
249     {
250         if (tmix->semanticRun >= PASSsemantic3)
251             return;
252         tmix->semanticRun = PASSsemantic3;
253         if (tmix->members)
254         {
255             sc = sc->push(tmix->argsym);
256             sc = sc->push(tmix);
257             for (size_t i = 0; i < tmix->members->length; i++)
258             {
259                 Dsymbol *s = (*tmix->members)[i];
260                 semantic3(s, sc);
261             }
262             sc = sc->pop();
263             sc->pop();
264         }
265     }
266 
visit(Module * mod)267     void visit(Module *mod)
268     {
269         //printf("Module::semantic3('%s'): parent = %p\n", mod->toChars(), mod->parent);
270         if (mod->semanticRun != PASSsemantic2done)
271             return;
272         mod->semanticRun = PASSsemantic3;
273 
274         // Note that modules get their own scope, from scratch.
275         // This is so regardless of where in the syntax a module
276         // gets imported, it is unaffected by context.
277         Scope *sc = Scope::createGlobal(mod);      // create root scope
278         //printf("Module = %p\n", sc.scopesym);
279 
280         // Pass 3 semantic routines: do initializers and function bodies
281         for (size_t i = 0; i < mod->members->length; i++)
282         {
283             Dsymbol *s = (*mod->members)[i];
284             //printf("Module %s: %s.semantic3()\n", mod->toChars(), s->toChars());
285             semantic3(s, sc);
286 
287             mod->runDeferredSemantic2();
288         }
289 
290         if (mod->userAttribDecl)
291         {
292             semantic3(mod->userAttribDecl, sc);
293         }
294 
295         sc = sc->pop();
296         sc->pop();
297         mod->semanticRun = PASSsemantic3done;
298     }
299 
visit(FuncDeclaration * funcdecl)300     void visit(FuncDeclaration *funcdecl)
301     {
302         VarDeclaration *_arguments = NULL;
303 
304         if (!funcdecl->parent)
305         {
306             if (global.errors)
307                 return;
308             //printf("FuncDeclaration::semantic3(%s '%s', sc = %p)\n", funcdecl->kind(), funcdecl->toChars(), sc);
309             assert(0);
310         }
311         if (funcdecl->errors || isError(funcdecl->parent))
312         {
313             funcdecl->errors = true;
314             return;
315         }
316         //printf("FuncDeclaration::semantic3('%s.%s', %p, sc = %p, loc = %s)\n", funcdecl->parent->toChars(), funcdecl->toChars(), funcdecl, sc, funcdecl->loc.toChars());
317         //fflush(stdout);
318         //printf("storage class = x%x %x\n", sc->stc, funcdecl->storage_class);
319         //{ static int x; if (++x == 2) *(char*)0=0; }
320         //printf("\tlinkage = %d\n", sc->linkage);
321 
322         if (funcdecl->ident == Id::assign && !funcdecl->inuse)
323         {
324             if (funcdecl->storage_class & STCinference)
325             {
326                 /* Bugzilla 15044: For generated opAssign function, any errors
327                  * from its body need to be gagged.
328                  */
329                 unsigned oldErrors = global.startGagging();
330                 funcdecl->inuse++;
331                 semantic3(funcdecl, sc);
332                 funcdecl->inuse--;
333                 if (global.endGagging(oldErrors))   // if errors happened
334                 {
335                     // Disable generated opAssign, because some members forbid identity assignment.
336                     funcdecl->storage_class |= STCdisable;
337                     funcdecl->fbody = NULL;   // remove fbody which contains the error
338                     funcdecl->semantic3Errors = false;
339                 }
340                 return;
341             }
342         }
343 
344         //printf(" sc->incontract = %d\n", (sc->flags & SCOPEcontract));
345         if (funcdecl->semanticRun >= PASSsemantic3)
346             return;
347         funcdecl->semanticRun = PASSsemantic3;
348         funcdecl->semantic3Errors = false;
349 
350         if (!funcdecl->type || funcdecl->type->ty != Tfunction)
351             return;
352         TypeFunction *f = (TypeFunction *)funcdecl->type;
353         if (!funcdecl->inferRetType && f->next->ty == Terror)
354             return;
355 
356         if (!funcdecl->fbody && funcdecl->inferRetType && !f->next)
357         {
358             funcdecl->error("has no function body with return type inference");
359             return;
360         }
361 
362         unsigned oldErrors = global.errors;
363 
364         if (funcdecl->frequires)
365         {
366             for (size_t i = 0; i < funcdecl->foverrides.length; i++)
367             {
368                 FuncDeclaration *fdv = funcdecl->foverrides[i];
369 
370                 if (fdv->fbody && !fdv->frequires)
371                 {
372                     funcdecl->error("cannot have an in contract when overriden function %s does not have an in contract", fdv->toPrettyChars());
373                     break;
374                 }
375             }
376         }
377 
378         // Remember whether we need to generate an 'out' contract.
379         const bool needEnsure = FuncDeclaration::needsFensure(funcdecl);
380 
381         if (funcdecl->fbody || funcdecl->frequires || needEnsure)
382         {
383             /* Symbol table into which we place parameters and nested functions,
384              * solely to diagnose name collisions.
385              */
386             funcdecl->localsymtab = new DsymbolTable();
387 
388             // Establish function scope
389             ScopeDsymbol *ss = new ScopeDsymbol();
390             // find enclosing scope symbol, might skip symbol-less CTFE and/or FuncExp scopes
391             for (Scope *scx = sc; ; scx = scx->enclosing)
392             {
393                 if (scx->scopesym)
394                 {
395                     ss->parent = scx->scopesym;
396                     break;
397                 }
398             }
399             ss->loc = funcdecl->loc;
400             ss->endlinnum = funcdecl->endloc.linnum;
401             Scope *sc2 = sc->push(ss);
402             sc2->func = funcdecl;
403             sc2->parent = funcdecl;
404             sc2->callSuper = 0;
405             sc2->sbreak = NULL;
406             sc2->scontinue = NULL;
407             sc2->sw = NULL;
408             sc2->fes = funcdecl->fes;
409             sc2->linkage = LINKd;
410             sc2->stc &= ~(STCauto | STCscope | STCstatic | STCextern | STCabstract |
411                           STCdeprecated | STCoverride |
412                           STC_TYPECTOR | STCfinal | STCtls | STCgshared | STCref | STCreturn |
413                           STCproperty | STCnothrow | STCpure | STCsafe | STCtrusted | STCsystem);
414             sc2->protection = Prot(Prot::public_);
415             sc2->explicitProtection = 0;
416             sc2->aligndecl = NULL;
417             if (funcdecl->ident != Id::require && funcdecl->ident != Id::ensure)
418                 sc2->flags = sc->flags & ~SCOPEcontract;
419             sc2->flags &= ~SCOPEcompile;
420             sc2->tf = NULL;
421             sc2->os = NULL;
422             sc2->noctor = 0;
423             sc2->userAttribDecl = NULL;
424             if (sc2->intypeof == 1) sc2->intypeof = 2;
425             sc2->fieldinit = NULL;
426             sc2->fieldinit_dim = 0;
427 
428             /* Note: When a lambda is defined immediately under aggregate member
429              * scope, it should be contextless due to prevent interior pointers.
430              * e.g.
431              *      // dg points 'this' - it's interior pointer
432              *      class C { int x; void delegate() dg = (){ this.x = 1; }; }
433              *
434              * However, lambdas could be used inside typeof, in order to check
435              * some expressions varidity at compile time. For such case the lambda
436              * body can access aggregate instance members.
437              * e.g.
438              *      class C { int x; static assert(is(typeof({ this.x = 1; }))); }
439              *
440              * To properly accept it, mark these lambdas as member functions.
441              */
442             if (FuncLiteralDeclaration *fld = funcdecl->isFuncLiteralDeclaration())
443             {
444                 if (AggregateDeclaration *ad = funcdecl->isMember2())
445                 {
446                     if (!sc->intypeof)
447                     {
448                         if (fld->tok == TOKdelegate)
449                             funcdecl->error("cannot be %s members", ad->kind());
450                         else
451                             fld->tok = TOKfunction;
452                     }
453                     else
454                     {
455                         if (fld->tok != TOKfunction)
456                             fld->tok = TOKdelegate;
457                     }
458                 }
459             }
460 
461             // Declare 'this'
462             AggregateDeclaration *ad = funcdecl->isThis();
463             funcdecl->vthis = funcdecl->declareThis(sc2, ad);
464             //printf("[%s] ad = %p vthis = %p\n", funcdecl->loc.toChars(), ad, funcdecl->vthis);
465             //if (funcdecl->vthis) printf("\tvthis->type = %s\n", funcdecl->vthis->type->toChars());
466 
467             // Declare hidden variable _arguments[] and _argptr
468             if (f->parameterList.varargs == VARARGvariadic)
469             {
470                 if (f->linkage == LINKd)
471                 {
472                     // Variadic arguments depend on Typeinfo being defined
473                     if (!global.params.useTypeInfo || !Type::dtypeinfo || !Type::typeinfotypelist)
474                     {
475                         if (!global.params.useTypeInfo)
476                             funcdecl->error("D-style variadic functions cannot be used with -betterC");
477                         else if (!Type::typeinfotypelist)
478                             funcdecl->error("`object.TypeInfo_Tuple` could not be found, but is implicitly used in D-style variadic functions");
479                         else
480                             funcdecl->error("`object.TypeInfo` could not be found, but is implicitly used in D-style variadic functions");
481                         fatal();
482                     }
483 
484                     // Declare _arguments[]
485                     funcdecl->v_arguments = new VarDeclaration(Loc(), Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL);
486                     funcdecl->v_arguments->storage_class |= STCtemp | STCparameter;
487                     dsymbolSemantic(funcdecl->v_arguments, sc2);
488                     sc2->insert(funcdecl->v_arguments);
489                     funcdecl->v_arguments->parent = funcdecl;
490 
491                     //Type *t = Type::typeinfo->type->constOf()->arrayOf();
492                     Type *t = Type::dtypeinfo->type->arrayOf();
493                     _arguments = new VarDeclaration(Loc(), t, Id::_arguments, NULL);
494                     _arguments->storage_class |= STCtemp;
495                     dsymbolSemantic(_arguments, sc2);
496                     sc2->insert(_arguments);
497                     _arguments->parent = funcdecl;
498                 }
499                 if (f->linkage == LINKd || f->parameterList.length())
500                 {
501                     // Declare _argptr
502                     Type *t = target.va_listType(funcdecl->loc, sc);
503                     funcdecl->v_argptr = new VarDeclaration(Loc(), t, Id::_argptr, NULL);
504                     funcdecl->v_argptr->storage_class |= STCtemp;
505                     dsymbolSemantic(funcdecl->v_argptr, sc2);
506                     sc2->insert(funcdecl->v_argptr);
507                     funcdecl->v_argptr->parent = funcdecl;
508                 }
509             }
510 
511             /* Declare all the function parameters as variables
512              * and install them in parameters[]
513              */
514             size_t nparams = f->parameterList.length();
515             if (nparams)
516             {
517                 /* parameters[] has all the tuples removed, as the back end
518                  * doesn't know about tuples
519                  */
520                 funcdecl->parameters = new VarDeclarations();
521                 funcdecl->parameters->reserve(nparams);
522                 for (size_t i = 0; i < nparams; i++)
523                 {
524                     Parameter *fparam = f->parameterList[i];
525                     Identifier *id = fparam->ident;
526                     StorageClass stc = 0;
527                     if (!id)
528                     {
529                         /* Generate identifier for un-named parameter,
530                          * because we need it later on.
531                          */
532                         fparam->ident = id = Identifier::generateId("_param_", i);
533                         stc |= STCtemp;
534                     }
535                     Type *vtype = fparam->type;
536                     VarDeclaration *v = new VarDeclaration(funcdecl->loc, vtype, id, NULL);
537                     //printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars());
538                     stc |= STCparameter;
539                     if (f->parameterList.varargs == VARARGtypesafe && i + 1 == nparams)
540                         stc |= STCvariadic;
541                     if (funcdecl->flags & FUNCFLAGinferScope && !(fparam->storageClass & STCscope))
542                         stc |= STCmaybescope;
543                     stc |= fparam->storageClass & (STCin | STCout | STCref | STCreturn | STCscope | STClazy | STCfinal | STC_TYPECTOR | STCnodtor);
544                     v->storage_class = stc;
545                     dsymbolSemantic(v, sc2);
546                     if (!sc2->insert(v))
547                         funcdecl->error("parameter %s.%s is already defined", funcdecl->toChars(), v->toChars());
548                     else
549                         funcdecl->parameters->push(v);
550                     funcdecl->localsymtab->insert(v);
551                     v->parent = funcdecl;
552                     if (fparam->userAttribDecl)
553                         v->userAttribDecl = fparam->userAttribDecl;
554                 }
555             }
556 
557             // Declare the tuple symbols and put them in the symbol table,
558             // but not in parameters[].
559             if (f->parameterList.parameters)
560             {
561                 for (size_t i = 0; i < f->parameterList.parameters->length; i++)
562                 {
563                     Parameter *fparam = (*f->parameterList.parameters)[i];
564 
565                     if (!fparam->ident)
566                         continue;                   // never used, so ignore
567                     if (fparam->type->ty == Ttuple)
568                     {
569                         TypeTuple *t = (TypeTuple *)fparam->type;
570                         size_t dim = Parameter::dim(t->arguments);
571                         Objects *exps = new Objects();
572                         exps->setDim(dim);
573                         for (size_t j = 0; j < dim; j++)
574                         {
575                             Parameter *narg = Parameter::getNth(t->arguments, j);
576                             assert(narg->ident);
577                             VarDeclaration *v = sc2->search(Loc(), narg->ident, NULL)->isVarDeclaration();
578                             assert(v);
579                             Expression *e = new VarExp(v->loc, v);
580                             (*exps)[j] = e;
581                         }
582                         assert(fparam->ident);
583                         TupleDeclaration *v = new TupleDeclaration(funcdecl->loc, fparam->ident, exps);
584                         //printf("declaring tuple %s\n", v->toChars());
585                         v->isexp = true;
586                         if (!sc2->insert(v))
587                             funcdecl->error("parameter %s.%s is already defined", funcdecl->toChars(), v->toChars());
588                         funcdecl->localsymtab->insert(v);
589                         v->parent = funcdecl;
590                     }
591                 }
592             }
593 
594             // Precondition invariant
595             Statement *fpreinv = NULL;
596             if (funcdecl->addPreInvariant())
597             {
598                 Expression *e = addInvariant(ad, funcdecl->vthis);
599                 if (e)
600                     fpreinv = new ExpStatement(Loc(), e);
601             }
602 
603             // Postcondition invariant
604             Statement *fpostinv = NULL;
605             if (funcdecl->addPostInvariant())
606             {
607                 Expression *e = addInvariant(ad, funcdecl->vthis);
608                 if (e)
609                     fpostinv = new ExpStatement(Loc(), e);
610             }
611 
612             // Pre/Postcondition contract
613             if (!funcdecl->fbody)
614                 funcdecl->buildEnsureRequire();
615 
616             Scope *scout = NULL;
617             if (needEnsure || funcdecl->addPostInvariant())
618             {
619                 if ((needEnsure && global.params.useOut == CHECKENABLEon) || fpostinv)
620                 {
621                     funcdecl->returnLabel = new LabelDsymbol(Id::returnLabel);
622                 }
623 
624                 // scope of out contract (need for vresult->semantic)
625                 ScopeDsymbol *sym = new ScopeDsymbol();
626                 sym->parent = sc2->scopesym;
627                 sym->loc = funcdecl->loc;
628                 sym->endlinnum = funcdecl->endloc.linnum;
629                 scout = sc2->push(sym);
630             }
631 
632             if (funcdecl->fbody)
633             {
634                 ScopeDsymbol *sym = new ScopeDsymbol();
635                 sym->parent = sc2->scopesym;
636                 sym->loc = funcdecl->loc;
637                 sym->endlinnum = funcdecl->endloc.linnum;
638                 sc2 = sc2->push(sym);
639 
640                 AggregateDeclaration *ad2 = funcdecl->isMember2();
641 
642                 /* If this is a class constructor
643                 */
644                 if (ad2 && funcdecl->isCtorDeclaration())
645                 {
646                     allocFieldinit(sc2, ad2->fields.length);
647                     for (size_t i = 0; i < ad2->fields.length; i++)
648                     {
649                         VarDeclaration *v = ad2->fields[i];
650                         v->ctorinit = 0;
651                     }
652                 }
653 
654                 bool inferRef = (f->isref && (funcdecl->storage_class & STCauto));
655 
656                 funcdecl->fbody = statementSemantic(funcdecl->fbody, sc2);
657                 if (!funcdecl->fbody)
658                     funcdecl->fbody = new CompoundStatement(Loc(), new Statements());
659 
660                 if (funcdecl->naked)
661                 {
662                     fpreinv = NULL;         // can't accommodate with no stack frame
663                     fpostinv = NULL;
664                 }
665 
666                 assert(funcdecl->type == f ||
667                        (funcdecl->type->ty == Tfunction &&
668                         f->purity == PUREimpure &&
669                         ((TypeFunction *)funcdecl->type)->purity >= PUREfwdref));
670                 f = (TypeFunction *)funcdecl->type;
671 
672                 if (funcdecl->inferRetType)
673                 {
674                     // If no return type inferred yet, then infer a void
675                     if (!f->next)
676                         f->next = Type::tvoid;
677                     if (f->checkRetType(funcdecl->loc))
678                         funcdecl->fbody = new ErrorStatement();
679                 }
680                 if (global.params.vcomplex && f->next != NULL)
681                     f->next->checkComplexTransition(funcdecl->loc);
682 
683                 if (funcdecl->returns && !funcdecl->fbody->isErrorStatement())
684                 {
685                     for (size_t i = 0; i < funcdecl->returns->length; )
686                     {
687                         Expression *exp = (*funcdecl->returns)[i]->exp;
688                         if (exp->op == TOKvar && ((VarExp *)exp)->var == funcdecl->vresult)
689                         {
690                             if (addReturn0(funcdecl))
691                                 exp->type = Type::tint32;
692                             else
693                                 exp->type = f->next;
694                             // Remove `return vresult;` from returns
695                             funcdecl->returns->remove(i);
696                             continue;
697                         }
698                         if (inferRef && f->isref && !exp->type->constConv(f->next))     // Bugzilla 13336
699                             f->isref = false;
700                         i++;
701                     }
702                 }
703                 if (f->isref)   // Function returns a reference
704                 {
705                     if (funcdecl->storage_class & STCauto)
706                         funcdecl->storage_class &= ~STCauto;
707                 }
708                 if (!target.isReturnOnStack(f, funcdecl->needThis()) || !funcdecl->checkNRVO())
709                     funcdecl->nrvo_can = 0;
710 
711                 if (funcdecl->fbody->isErrorStatement())
712                     ;
713                 else if (funcdecl->isStaticCtorDeclaration())
714                 {
715                     /* It's a static constructor. Ensure that all
716                      * ctor consts were initialized.
717                      */
718                     ScopeDsymbol *pd = funcdecl->toParent()->isScopeDsymbol();
719                     for (size_t i = 0; i < pd->members->length; i++)
720                     {
721                         Dsymbol *s = (*pd->members)[i];
722                         s->checkCtorConstInit();
723                     }
724                 }
725                 else if (ad2 && funcdecl->isCtorDeclaration())
726                 {
727                     ClassDeclaration *cd = ad2->isClassDeclaration();
728 
729                     // Verify that all the ctorinit fields got initialized
730                     if (!(sc2->callSuper & CSXthis_ctor))
731                     {
732                         for (size_t i = 0; i < ad2->fields.length; i++)
733                         {
734                             VarDeclaration *v = ad2->fields[i];
735                             if (v->isThisDeclaration())
736                                 continue;
737                             if (v->ctorinit == 0)
738                             {
739                                 /* Current bugs in the flow analysis:
740                                  * 1. union members should not produce error messages even if
741                                  *    not assigned to
742                                  * 2. structs should recognize delegating opAssign calls as well
743                                  *    as delegating calls to other constructors
744                                  */
745                                 if (v->isCtorinit() && !v->type->isMutable() && cd)
746                                     funcdecl->error("missing initializer for %s field %s", MODtoChars(v->type->mod), v->toChars());
747                                 else if (v->storage_class & STCnodefaultctor)
748                                     error(funcdecl->loc, "field %s must be initialized in constructor", v->toChars());
749                                 else if (v->type->needsNested())
750                                     error(funcdecl->loc, "field %s must be initialized in constructor, because it is nested struct", v->toChars());
751                             }
752                             else
753                             {
754                                 bool mustInit = (v->storage_class & STCnodefaultctor ||
755                                                  v->type->needsNested());
756                                 if (mustInit && !(sc2->fieldinit[i] & CSXthis_ctor))
757                                 {
758                                     funcdecl->error("field %s must be initialized but skipped", v->toChars());
759                                 }
760                             }
761                         }
762                     }
763                     freeFieldinit(sc2);
764 
765                     if (cd &&
766                         !(sc2->callSuper & CSXany_ctor) &&
767                         cd->baseClass && cd->baseClass->ctor)
768                     {
769                         sc2->callSuper = 0;
770 
771                         // Insert implicit super() at start of fbody
772                         FuncDeclaration *fd = resolveFuncCall(Loc(), sc2, cd->baseClass->ctor, NULL, funcdecl->vthis->type, NULL, 1);
773                         if (!fd)
774                         {
775                             funcdecl->error("no match for implicit super() call in constructor");
776                         }
777                         else if (fd->storage_class & STCdisable)
778                         {
779                             funcdecl->error("cannot call super() implicitly because it is annotated with @disable");
780                         }
781                         else
782                         {
783                             Expression *e1 = new SuperExp(Loc());
784                             Expression *e = new CallExp(Loc(), e1);
785                             e = expressionSemantic(e, sc2);
786 
787                             Statement *s = new ExpStatement(Loc(), e);
788                             funcdecl->fbody = new CompoundStatement(Loc(), s, funcdecl->fbody);
789                         }
790                     }
791                     //printf("callSuper = x%x\n", sc2->callSuper);
792                 }
793 
794                 /* https://issues.dlang.org/show_bug.cgi?id=17502
795                  * Wait until after the return type has been inferred before
796                  * generating the contracts for this function, and merging contracts
797                  * from overrides.
798                  *
799                  * https://issues.dlang.org/show_bug.cgi?id=17893
800                  * However should take care to generate this before inferered
801                  * function attributes are applied, such as 'nothrow'.
802                  *
803                  * This was originally at the end of the first semantic pass, but
804                  * required a fix-up to be done here for the '__result' variable
805                  * type of __ensure() inside auto functions, but this didn't work
806                  * if the out parameter was implicit.
807                  */
808                 funcdecl->buildEnsureRequire();
809 
810                 int blockexit = BEnone;
811                 if (!funcdecl->fbody->isErrorStatement())
812                 {
813                     // Check for errors related to 'nothrow'.
814                     unsigned int nothrowErrors = global.errors;
815                     blockexit = blockExit(funcdecl->fbody, funcdecl, f->isnothrow);
816                     if (f->isnothrow && (global.errors != nothrowErrors))
817                         error(funcdecl->loc, "nothrow %s `%s` may throw", funcdecl->kind(), funcdecl->toPrettyChars());
818                     if (funcdecl->flags & FUNCFLAGnothrowInprocess)
819                     {
820                         if (funcdecl->type == f) f = (TypeFunction *)f->copy();
821                         f->isnothrow = !(blockexit & BEthrow);
822                     }
823                 }
824 
825                 if (funcdecl->fbody->isErrorStatement())
826                     ;
827                 else if (ad2 && funcdecl->isCtorDeclaration())
828                 {
829                     /* Append:
830                      *  return this;
831                      * to function body
832                      */
833                     if (blockexit & BEfallthru)
834                     {
835                         Statement *s = new ReturnStatement(funcdecl->loc, NULL);
836                         s = statementSemantic(s, sc2);
837                         funcdecl->fbody = new CompoundStatement(funcdecl->loc, funcdecl->fbody, s);
838                         funcdecl->hasReturnExp |= (funcdecl->hasReturnExp & 1 ? 16 : 1);
839                     }
840                 }
841                 else if (funcdecl->fes)
842                 {
843                     // For foreach(){} body, append a return 0;
844                     if (blockexit & BEfallthru)
845                     {
846                         Expression *e = new IntegerExp(0);
847                         Statement *s = new ReturnStatement(Loc(), e);
848                         funcdecl->fbody = new CompoundStatement(Loc(), funcdecl->fbody, s);
849                         funcdecl->hasReturnExp |= (funcdecl->hasReturnExp & 1 ? 16 : 1);
850                     }
851                     assert(!funcdecl->returnLabel);
852                 }
853                 else if (f->next->ty == Tnoreturn)
854                 {
855                 }
856                 else
857                 {
858                     const bool inlineAsm = (funcdecl->hasReturnExp & 8) != 0;
859                     if ((blockexit & BEfallthru) && f->next->ty != Tvoid && !inlineAsm)
860                     {
861                         if (!funcdecl->hasReturnExp)
862                             funcdecl->error("has no `return` statement, but is expected to return a value of type `%s`", f->next->toChars());
863                         else
864                             funcdecl->error("no `return exp;` or `assert(0);` at end of function");
865                     }
866                 }
867 
868                 if (funcdecl->returns)
869                 {
870                     bool implicit0 = addReturn0(funcdecl);
871                     Type *tret = implicit0 ? Type::tint32 : f->next;
872                     assert(tret->ty != Tvoid);
873                     if (funcdecl->vresult || funcdecl->returnLabel)
874                         funcdecl->buildResultVar(scout ? scout : sc2, tret);
875 
876                     /* Cannot move this loop into NrvoWalker, because
877                      * returns[i] may be in the nested delegate for foreach-body.
878                      */
879                     for (size_t i = 0; i < funcdecl->returns->length; i++)
880                     {
881                         ReturnStatement *rs = (*funcdecl->returns)[i];
882                         Expression *exp = rs->exp;
883                         if (exp->op == TOKerror)
884                             continue;
885                         if (tret->ty == Terror)
886                         {
887                             // Bugzilla 13702
888                             exp = checkGC(sc2, exp);
889                             continue;
890                         }
891 
892                         if (!exp->implicitConvTo(tret) &&
893                             funcdecl->parametersIntersect(exp->type))
894                         {
895                             if (exp->type->immutableOf()->implicitConvTo(tret))
896                                 exp = exp->castTo(sc2, exp->type->immutableOf());
897                             else if (exp->type->wildOf()->implicitConvTo(tret))
898                                 exp = exp->castTo(sc2, exp->type->wildOf());
899                         }
900                         exp = exp->implicitCastTo(sc2, tret);
901 
902                         if (f->isref)
903                         {
904                             // Function returns a reference
905                             exp = exp->toLvalue(sc2, exp);
906                             checkReturnEscapeRef(sc2, exp, false);
907                         }
908                         else
909                         {
910                             exp = exp->optimize(WANTvalue);
911 
912                             /* Bugzilla 10789:
913                              * If NRVO is not possible, all returned lvalues should call their postblits.
914                              */
915                             if (!funcdecl->nrvo_can)
916                                 exp = doCopyOrMove(sc2, exp);
917 
918                             if (tret->hasPointers())
919                                 checkReturnEscape(sc2, exp, false);
920                         }
921 
922                         exp = checkGC(sc2, exp);
923 
924                         if (funcdecl->vresult)
925                         {
926                             // Create: return vresult = exp;
927                             exp = new BlitExp(rs->loc, funcdecl->vresult, exp);
928                             exp->type = funcdecl->vresult->type;
929 
930                             if (rs->caseDim)
931                                 exp = Expression::combine(exp, new IntegerExp(rs->caseDim));
932                         }
933                         else if (funcdecl->tintro && !tret->equals(funcdecl->tintro->nextOf()))
934                         {
935                             exp = exp->implicitCastTo(sc2, funcdecl->tintro->nextOf());
936                         }
937                         rs->exp = exp;
938                     }
939                 }
940                 if (funcdecl->nrvo_var || funcdecl->returnLabel)
941                 {
942                     NrvoWalker nw;
943                     nw.fd = funcdecl;
944                     nw.sc = sc2;
945                     nw.visitStmt(funcdecl->fbody);
946                 }
947 
948                 sc2 = sc2->pop();
949             }
950 
951             funcdecl->frequire = funcdecl->mergeFrequire(funcdecl->frequire);
952             funcdecl->fensure = funcdecl->mergeFensure(funcdecl->fensure, Id::result);
953 
954             Statement *freq = funcdecl->frequire;
955             Statement *fens = funcdecl->fensure;
956 
957             /* Do the semantic analysis on the [in] preconditions and
958              * [out] postconditions.
959              */
960             if (freq)
961             {
962                 /* frequire is composed of the [in] contracts
963                 */
964                 ScopeDsymbol *sym = new ScopeDsymbol();
965                 sym->parent = sc2->scopesym;
966                 sym->loc = funcdecl->loc;
967                 sym->endlinnum = funcdecl->endloc.linnum;
968                 sc2 = sc2->push(sym);
969                 sc2->flags = (sc2->flags & ~SCOPEcontract) | SCOPErequire;
970 
971                 // BUG: need to error if accessing out parameters
972                 // BUG: need to disallow returns and throws
973                 // BUG: verify that all in and ref parameters are read
974                 freq = statementSemantic(freq, sc2);
975                 blockExit(freq, funcdecl, false);
976 
977                 sc2 = sc2->pop();
978 
979                 if (global.params.useIn == CHECKENABLEoff)
980                     freq = NULL;
981             }
982 
983             if (fens)
984             {
985                 /* fensure is composed of the [out] contracts
986                 */
987                 if (f->next->ty == Tvoid && funcdecl->fensures)
988                 {
989                     for (size_t i = 0; i < funcdecl->fensures->length; i++)
990                     {
991                         Ensure e = (*funcdecl->fensures)[i];
992                         if (e.id)
993                         {
994                             funcdecl->error(e.ensure->loc, "`void` functions have no result");
995                             //fens = NULL;
996                         }
997                     }
998                 }
999 
1000                 sc2 = scout;    //push
1001                 sc2->flags = (sc2->flags & ~SCOPEcontract) | SCOPEensure;
1002 
1003                 // BUG: need to disallow returns and throws
1004                 if (funcdecl->fensure && f->next->ty != Tvoid)
1005                     funcdecl->buildResultVar(scout, f->next);
1006 
1007                 fens = statementSemantic(fens, sc2);
1008                 blockExit(fens, funcdecl, false);
1009 
1010                 sc2 = sc2->pop();
1011 
1012                 if (global.params.useOut == CHECKENABLEoff)
1013                     fens = NULL;
1014             }
1015 
1016             if (funcdecl->fbody && funcdecl->fbody->isErrorStatement())
1017                 ;
1018             else
1019             {
1020                 Statements *a = new Statements();
1021 
1022                 // Merge in initialization of 'out' parameters
1023                 if (funcdecl->parameters)
1024                 {
1025                     for (size_t i = 0; i < funcdecl->parameters->length; i++)
1026                     {
1027                         VarDeclaration *v = (*funcdecl->parameters)[i];
1028                         if (v->storage_class & STCout)
1029                         {
1030                             assert(v->_init);
1031                             ExpInitializer *ie = v->_init->isExpInitializer();
1032                             assert(ie);
1033                             if (ie->exp->op == TOKconstruct)
1034                                 ie->exp->op = TOKassign; // construction occured in parameter processing
1035                             a->push(new ExpStatement(Loc(), ie->exp));
1036                         }
1037                     }
1038                 }
1039 
1040                 if (funcdecl->v_argptr)
1041                 {
1042                     // Handled in FuncDeclaration::toObjFile
1043                     funcdecl->v_argptr->_init = new VoidInitializer(funcdecl->loc);
1044                 }
1045 
1046                 if (_arguments)
1047                 {
1048                     /* Advance to elements[] member of TypeInfo_Tuple with:
1049                      *  _arguments = v_arguments.elements;
1050                      */
1051                     Expression *e = new VarExp(Loc(), funcdecl->v_arguments);
1052                     e = new DotIdExp(Loc(), e, Id::elements);
1053                     e = new ConstructExp(Loc(), _arguments, e);
1054                     e = expressionSemantic(e, sc2);
1055 
1056                     _arguments->_init = new ExpInitializer(Loc(), e);
1057                     DeclarationExp *de = new DeclarationExp(Loc(), _arguments);
1058                     a->push(new ExpStatement(Loc(), de));
1059                 }
1060 
1061                 // Merge contracts together with body into one compound statement
1062 
1063                 if (freq || fpreinv)
1064                 {
1065                     if (!freq)
1066                         freq = fpreinv;
1067                     else if (fpreinv)
1068                         freq = new CompoundStatement(Loc(), freq, fpreinv);
1069 
1070                     a->push(freq);
1071                 }
1072 
1073                 if (funcdecl->fbody)
1074                     a->push(funcdecl->fbody);
1075 
1076                 if (fens || fpostinv)
1077                 {
1078                     if (!fens)
1079                         fens = fpostinv;
1080                     else if (fpostinv)
1081                         fens = new CompoundStatement(Loc(), fpostinv, fens);
1082 
1083                     LabelStatement *ls = new LabelStatement(Loc(), Id::returnLabel, fens);
1084                     funcdecl->returnLabel->statement = ls;
1085                     a->push(funcdecl->returnLabel->statement);
1086 
1087                     if (f->next->ty != Tvoid && funcdecl->vresult)
1088                     {
1089                         // Create: return vresult;
1090                         Expression *e = new VarExp(Loc(), funcdecl->vresult);
1091                         if (funcdecl->tintro)
1092                         {
1093                             e = e->implicitCastTo(sc, funcdecl->tintro->nextOf());
1094                             e = expressionSemantic(e, sc);
1095                         }
1096                         ReturnStatement *s = new ReturnStatement(Loc(), e);
1097                         a->push(s);
1098                     }
1099                 }
1100                 if (addReturn0(funcdecl))
1101                 {
1102                     // Add a return 0; statement
1103                     Statement *s = new ReturnStatement(Loc(), new IntegerExp(0));
1104                     a->push(s);
1105                 }
1106 
1107                 Statement *sbody = new CompoundStatement(Loc(), a);
1108                 /* Append destructor calls for parameters as finally blocks.
1109                 */
1110                 if (funcdecl->parameters)
1111                 {
1112                     for (size_t i = 0; i < funcdecl->parameters->length; i++)
1113                     {
1114                         VarDeclaration *v = (*funcdecl->parameters)[i];
1115 
1116                         if (v->storage_class & (STCref | STCout | STClazy))
1117                             continue;
1118 
1119                         if (v->needsScopeDtor())
1120                         {
1121                             // same with ExpStatement.scopeCode()
1122                             Statement *s = new DtorExpStatement(Loc(), v->edtor, v);
1123                             v->storage_class |= STCnodtor;
1124 
1125                             s = statementSemantic(s, sc2);
1126 
1127                             bool isnothrow = f->isnothrow & !(funcdecl->flags & FUNCFLAGnothrowInprocess);
1128                             int blockexit = blockExit(s, funcdecl, isnothrow);
1129                             if (f->isnothrow && isnothrow && blockexit & BEthrow)
1130                                 error(funcdecl->loc, "nothrow %s `%s` may throw", funcdecl->kind(), funcdecl->toPrettyChars());
1131                             if (funcdecl->flags & FUNCFLAGnothrowInprocess && blockexit & BEthrow)
1132                                 f->isnothrow = false;
1133                             if (blockExit(sbody, funcdecl, f->isnothrow) == BEfallthru)
1134                                 sbody = new CompoundStatement(Loc(), sbody, s);
1135                             else
1136                                 sbody = new TryFinallyStatement(Loc(), sbody, s);
1137                         }
1138                     }
1139                 }
1140                 // from this point on all possible 'throwers' are checked
1141                 funcdecl->flags &= ~FUNCFLAGnothrowInprocess;
1142 
1143                 if (funcdecl->isSynchronized())
1144                 {
1145                     /* Wrap the entire function body in a synchronized statement
1146                     */
1147                     ClassDeclaration *cd = funcdecl->isThis() ? funcdecl->isThis()->isClassDeclaration() : funcdecl->parent->isClassDeclaration();
1148 
1149                     if (cd)
1150                     {
1151                         if (target.libraryObjectMonitors(funcdecl, sbody))
1152                         {
1153                             Expression *vsync;
1154                             if (funcdecl->isStatic())
1155                             {
1156                                 // The monitor is in the ClassInfo
1157                                 vsync = new DotIdExp(funcdecl->loc, resolve(funcdecl->loc, sc2, cd, false), Id::classinfo);
1158                             }
1159                             else
1160                             {
1161                                 // 'this' is the monitor
1162                                 vsync = new VarExp(funcdecl->loc, funcdecl->vthis);
1163                             }
1164                             sbody = new PeelStatement(sbody);       // don't redo semantic()
1165                             sbody = new SynchronizedStatement(funcdecl->loc, vsync, sbody);
1166                             sbody = statementSemantic(sbody, sc2);
1167                         }
1168                     }
1169                     else
1170                     {
1171                         funcdecl->error("synchronized function %s must be a member of a class", funcdecl->toChars());
1172                     }
1173                 }
1174 
1175                 // If declaration has no body, don't set sbody to prevent incorrect codegen.
1176                 if (funcdecl->fbody || allowsContractWithoutBody(funcdecl))
1177                     funcdecl->fbody = sbody;
1178             }
1179 
1180             // Fix up forward-referenced gotos
1181             if (funcdecl->gotos)
1182             {
1183                 for (size_t i = 0; i < funcdecl->gotos->length; ++i)
1184                 {
1185                     (*funcdecl->gotos)[i]->checkLabel();
1186                 }
1187             }
1188 
1189             if (funcdecl->naked && (funcdecl->fensures || funcdecl->frequires))
1190                 funcdecl->error("naked assembly functions with contracts are not supported");
1191 
1192             sc2->callSuper = 0;
1193             sc2->pop();
1194         }
1195 
1196         if (funcdecl->checkClosure())
1197         {
1198             // We should be setting errors here instead of relying on the global error count.
1199             //errors = true;
1200         }
1201 
1202         /* If function survived being marked as impure, then it is pure
1203         */
1204         if (funcdecl->flags & FUNCFLAGpurityInprocess)
1205         {
1206             funcdecl->flags &= ~FUNCFLAGpurityInprocess;
1207             if (funcdecl->type == f)
1208                 f = (TypeFunction *)f->copy();
1209             f->purity = PUREfwdref;
1210         }
1211 
1212         if (funcdecl->flags & FUNCFLAGsafetyInprocess)
1213         {
1214             funcdecl->flags &= ~FUNCFLAGsafetyInprocess;
1215             if (funcdecl->type == f)
1216                 f = (TypeFunction *)f->copy();
1217             f->trust = TRUSTsafe;
1218         }
1219 
1220         if (funcdecl->flags & FUNCFLAGnogcInprocess)
1221         {
1222             funcdecl->flags &= ~FUNCFLAGnogcInprocess;
1223             if (funcdecl->type == f)
1224                 f = (TypeFunction *)f->copy();
1225             f->isnogc = true;
1226         }
1227 
1228         if (funcdecl->flags & FUNCFLAGreturnInprocess)
1229         {
1230             funcdecl->flags &= ~FUNCFLAGreturnInprocess;
1231             if (funcdecl->storage_class & STCreturn)
1232             {
1233                 if (funcdecl->type == f)
1234                     f = (TypeFunction *)f->copy();
1235                 f->isreturn = true;
1236             }
1237         }
1238 
1239         funcdecl->flags &= ~FUNCFLAGinferScope;
1240 
1241         // Infer STCscope
1242         if (funcdecl->parameters)
1243         {
1244             size_t nfparams = f->parameterList.length();
1245             assert(nfparams == funcdecl->parameters->length);
1246             for (size_t u = 0; u < funcdecl->parameters->length; u++)
1247             {
1248                 VarDeclaration *v = (*funcdecl->parameters)[u];
1249                 if (v->storage_class & STCmaybescope)
1250                 {
1251                     //printf("Inferring scope for %s\n", v->toChars());
1252                     Parameter *p = f->parameterList[u];
1253                     v->storage_class &= ~STCmaybescope;
1254                     v->storage_class |= STCscope | STCscopeinferred;
1255                     p->storageClass |= STCscope | STCscopeinferred;
1256                     assert(!(p->storageClass & STCmaybescope));
1257                 }
1258             }
1259         }
1260 
1261         if (funcdecl->vthis && funcdecl->vthis->storage_class & STCmaybescope)
1262         {
1263             funcdecl->vthis->storage_class &= ~STCmaybescope;
1264             funcdecl->vthis->storage_class |= STCscope | STCscopeinferred;
1265             f->isscope = true;
1266             f->isscopeinferred = true;
1267         }
1268 
1269         // reset deco to apply inference result to mangled name
1270         if (f != funcdecl->type)
1271             f->deco = NULL;
1272 
1273         // Do semantic type AFTER pure/nothrow inference.
1274         if (!f->deco && funcdecl->ident != Id::xopEquals && funcdecl->ident != Id::xopCmp)
1275         {
1276             sc = sc->push();
1277             if (funcdecl->isCtorDeclaration()) // Bugzilla #15665
1278                 sc->flags |= SCOPEctor;
1279             sc->stc = 0;
1280             sc->linkage = funcdecl->linkage;  // Bugzilla 8496
1281             funcdecl->type = typeSemantic(f, funcdecl->loc, sc);
1282             sc = sc->pop();
1283         }
1284 
1285         /* If this function had instantiated with gagging, error reproduction will be
1286          * done by TemplateInstance::semantic.
1287          * Otherwise, error gagging should be temporarily ungagged by functionSemantic3.
1288          */
1289         funcdecl->semanticRun = PASSsemantic3done;
1290         funcdecl->semantic3Errors = (global.errors != oldErrors) || (funcdecl->fbody && funcdecl->fbody->isErrorStatement());
1291         if (funcdecl->type->ty == Terror)
1292             funcdecl->errors = true;
1293         //printf("-FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", funcdecl->parent->toChars(), funcdecl->toChars(), sc, funcdecl->loc.toChars());
1294         //fflush(stdout);
1295     }
1296 
visit(Nspace * ns)1297     void visit(Nspace *ns)
1298     {
1299         if (ns->semanticRun >= PASSsemantic3)
1300             return;
1301         ns->semanticRun = PASSsemantic3;
1302         if (ns->members)
1303         {
1304             sc = sc->push(ns);
1305             sc->linkage = LINKcpp;
1306             for (size_t i = 0; i < ns->members->length; i++)
1307             {
1308                 Dsymbol *s = (*ns->members)[i];
1309                 semantic3(s, sc);
1310             }
1311             sc->pop();
1312         }
1313     }
1314 
visit(AttribDeclaration * ad)1315     void visit(AttribDeclaration *ad)
1316     {
1317         Dsymbols *d = ad->include(sc);
1318 
1319         if (d)
1320         {
1321             Scope *sc2 = ad->newScope(sc);
1322 
1323             for (size_t i = 0; i < d->length; i++)
1324             {
1325                 Dsymbol *s = (*d)[i];
1326                 semantic3(s, sc2);
1327             }
1328 
1329             if (sc2 != sc)
1330                 sc2->pop();
1331         }
1332     }
1333 
visit(AggregateDeclaration * ad)1334     void visit(AggregateDeclaration *ad)
1335     {
1336         //printf("AggregateDeclaration::semantic3(%s) type = %s, errors = %d\n", ad->toChars(), ad->type->toChars(), ad->errors);
1337         if (!ad->members)
1338             return;
1339 
1340         StructDeclaration *sd = ad->isStructDeclaration();
1341         if (!sc)    // from runDeferredSemantic3 for TypeInfo generation
1342         {
1343             assert(sd);
1344             sd->semanticTypeInfoMembers();
1345             return;
1346         }
1347 
1348         Scope *sc2 = ad->newScope(sc);
1349 
1350         for (size_t i = 0; i < ad->members->length; i++)
1351         {
1352             Dsymbol *s = (*ad->members)[i];
1353             semantic3(s, sc2);
1354         }
1355 
1356         sc2->pop();
1357 
1358         // don't do it for unused deprecated types
1359         // or error types
1360         if (!ad->getRTInfo && Type::rtinfo &&
1361             (!ad->isDeprecated() || global.params.useDeprecated != DIAGNOSTICerror) &&
1362             (ad->type && ad->type->ty != Terror))
1363         {
1364             // Evaluate: RTinfo!type
1365             Objects *tiargs = new Objects();
1366             tiargs->push(ad->type);
1367             TemplateInstance *ti = new TemplateInstance(ad->loc, Type::rtinfo, tiargs);
1368 
1369             Scope *sc3 = ti->tempdecl->_scope->startCTFE();
1370             sc3->tinst = sc->tinst;
1371             sc3->minst = sc->minst;
1372             if (ad->isDeprecated())
1373                 sc3->stc |= STCdeprecated;
1374 
1375             dsymbolSemantic(ti, sc3);
1376             semantic2(ti, sc3);
1377             semantic3(ti, sc3);
1378             Expression *e = resolve(Loc(), sc3, ti->toAlias(), false);
1379 
1380             sc3->endCTFE();
1381 
1382             e = e->ctfeInterpret();
1383             ad->getRTInfo = e;
1384         }
1385 
1386         if (sd)
1387             sd->semanticTypeInfoMembers();
1388         ad->semanticRun = PASSsemantic3done;
1389     }
1390 };
1391 
1392 /*************************************
1393  * Does semantic analysis on function bodies.
1394  */
semantic3(Dsymbol * dsym,Scope * sc)1395 void semantic3(Dsymbol *dsym, Scope *sc)
1396 {
1397     Semantic3Visitor v(sc);
1398     dsym->accept(&v);
1399 }
1400