Page MenuHomePhabricator

[Sema] Fix redeclaration contexts for enumerators in C
ClosedPublic

Authored by aaron.ballman on Sep 21 2018, 5:18 PM.

Details

Summary

In C, enumerators are not hoisted into, say, a struct decl context when the enumeration is declared inside of a struct. Instead, the enumerators are hoisted into the translation unit decl context. This patch fixes getRedeclContext() to skip records as well as transparent contexts when the original context is an enumeration. This allows us to catch enumerator redeclarations as well as silent name hiding + miscompiles.

This patch address PR15071.

Diff Detail

Event Timeline

aaron.ballman created this revision.Sep 21 2018, 5:18 PM
majnemer added inline comments.
lib/AST/DeclBase.cpp
1711–1712

Seems simpler as:

while ((SkipRecords && Ctx->isRecord()) || Ctx->isTransparentContext())
aaron.ballman marked an inline comment as done.

Updated based on review feedback.

aaron.ballman added inline comments.Sep 28 2018, 9:17 AM
lib/AST/DeclBase.cpp
1711–1712

Agreed; I've changed it.

jsji removed a subscriber: jsji.Sep 28 2018, 9:23 AM
rsmith added inline comments.Oct 19 2018, 4:02 PM
lib/AST/DeclBase.cpp
1704–1705

Nit: "the redeclaration context for enumerators is the translation unit" is not entirely accurate. The point instead is that a record type is only the redeclaration context for the fields of that record, so if we arrive at that context after skipping anything else, we should skip the record as well. (The check for "Enum" here is a red herring in that regard, but it happens to be correct because enumerations are the only transparent context that can exist within a struct or union currently.)

rsmith accepted this revision.Oct 19 2018, 4:02 PM

(Looks fine with a suitably-adjusted comment.)

This revision is now accepted and ready to land.Oct 19 2018, 4:02 PM

Committed (with improved comment) in r345073.