@@ -290,6 +290,27 @@ static void tryDiagnoseUnnecessaryCastOverOptionSet(ASTContext &Ctx,
290
290
.fixItRemove (SourceRange (ME->getDotLoc (), E->getEndLoc ()));
291
291
}
292
292
293
+ // / Check that a labeled statement doesn't shadow another statement with the
294
+ // / same label.
295
+ static void checkLabeledStmtShadowing (
296
+ ASTContext &ctx, SourceFile *sourceFile, LabeledStmt *ls) {
297
+ auto name = ls->getLabelInfo ().Name ;
298
+ if (name.empty () || !sourceFile || ls->getStartLoc ().isInvalid ())
299
+ return ;
300
+
301
+ auto activeLabeledStmtsVec = ASTScope::lookupLabeledStmts (
302
+ sourceFile, ls->getStartLoc ());
303
+ auto activeLabeledStmts = llvm::makeArrayRef (activeLabeledStmtsVec);
304
+ for (auto prevLS : activeLabeledStmts.slice (1 )) {
305
+ if (prevLS->getLabelInfo ().Name == name) {
306
+ ctx.Diags .diagnose (
307
+ ls->getLabelInfo ().Loc , diag::label_shadowed, name);
308
+ ctx.Diags .diagnose (
309
+ prevLS->getLabelInfo ().Loc , diag::invalid_redecl_prev, name);
310
+ }
311
+ }
312
+ }
313
+
293
314
namespace {
294
315
class StmtChecker : public StmtVisitor <StmtChecker, Stmt*> {
295
316
public:
@@ -332,50 +353,39 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
332
353
StmtChecker &SC;
333
354
AddLabeledStmt (StmtChecker &SC, LabeledStmt *LS) : SC(SC) {
334
355
// Verify that we don't have label shadowing.
335
- if (!LS->getLabelInfo ().Name .empty ())
336
- for (auto PrevLS : SC.ActiveLabeledStmts ) {
337
- if (PrevLS->getLabelInfo ().Name == LS->getLabelInfo ().Name ) {
338
- auto &DE = SC.getASTContext ().Diags ;
339
- DE.diagnose (LS->getLabelInfo ().Loc ,
340
- diag::label_shadowed, LS->getLabelInfo ().Name );
341
- DE.diagnose (PrevLS->getLabelInfo ().Loc ,
342
- diag::invalid_redecl_prev,
343
- PrevLS->getLabelInfo ().Name );
344
- }
345
- }
356
+ auto sourceFile = SC.DC ->getParentSourceFile ();
357
+ checkLabeledStmtShadowing (SC.getASTContext (), sourceFile, LS);
346
358
347
359
// In any case, remember that we're in this labeled statement so that
348
360
// break and continue are aware of it.
349
361
SC.ActiveLabeledStmts .push_back (LS);
350
362
351
363
// Verify that the ASTScope-based query for active labeled statements
352
364
// is equivalent to what we have here.
353
- if (LS->getStartLoc ().isValid ()) {
354
- if (auto sourceFile = SC.DC ->getParentSourceFile ()) {
355
- // The labeled statements from ASTScope lookup have the
356
- // innermost labeled statement first, so reverse it to
357
- // match the data structure maintained here.
358
- auto activeFromASTScope = ASTScope::lookupLabeledStmts (
359
- sourceFile, LS->getStartLoc ());
360
- assert (activeFromASTScope.front () == LS);
361
- std::reverse (activeFromASTScope.begin (), activeFromASTScope.end ());
362
- if (activeFromASTScope != SC.ActiveLabeledStmts ) {
363
- llvm::errs () << " Old: " ;
364
- llvm::interleave (SC.ActiveLabeledStmts , [&](LabeledStmt *LS) {
365
- llvm::errs () << LS;
366
- }, [&] {
367
- llvm::errs () << ' ' ;
368
- });
369
- llvm::errs () << " \n New: " ;
370
- llvm::interleave (activeFromASTScope, [&](LabeledStmt *LS) {
371
- llvm::errs () << LS;
372
- }, [&] {
373
- llvm::errs () << ' ' ;
374
- });
375
- llvm::errs () << " \n " ;
376
- }
377
- assert (activeFromASTScope == SC.ActiveLabeledStmts );
365
+ if (LS->getStartLoc ().isValid () && sourceFile) {
366
+ // The labeled statements from ASTScope lookup have the
367
+ // innermost labeled statement first, so reverse it to
368
+ // match the data structure maintained here.
369
+ auto activeFromASTScope = ASTScope::lookupLabeledStmts (
370
+ sourceFile, LS->getStartLoc ());
371
+ assert (activeFromASTScope.front () == LS);
372
+ std::reverse (activeFromASTScope.begin (), activeFromASTScope.end ());
373
+ if (activeFromASTScope != SC.ActiveLabeledStmts ) {
374
+ llvm::errs () << " Old: " ;
375
+ llvm::interleave (SC.ActiveLabeledStmts , [&](LabeledStmt *LS) {
376
+ llvm::errs () << LS;
377
+ }, [&] {
378
+ llvm::errs () << ' ' ;
379
+ });
380
+ llvm::errs () << " \n New: " ;
381
+ llvm::interleave (activeFromASTScope, [&](LabeledStmt *LS) {
382
+ llvm::errs () << LS;
383
+ }, [&] {
384
+ llvm::errs () << ' ' ;
385
+ });
386
+ llvm::errs () << " \n " ;
378
387
}
388
+ assert (activeFromASTScope == SC.ActiveLabeledStmts );
379
389
}
380
390
}
381
391
~AddLabeledStmt () {
0 commit comments