r279374 - [Sema] Don't crash on scanf on forward-declared enums.
Vitaly Buka via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 21 18:17:21 PDT 2016
flake
On Sat, Aug 20, 2016 at 11:30 AM Benjamin Kramer <benny.kra at gmail.com>
wrote:
> It cycled back to green. flake?
>
> On Sat, Aug 20, 2016 at 7:27 PM, Vitaly Buka <vitalybuka at google.com>
> wrote:
> > msan is not happy about this change
> >
> http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/15681/steps/check-llvm%20msan/logs/stdio
> >
> > On Sat, Aug 20, 2016 at 9:59 AM Benjamin Kramer via cfe-commits
> > <cfe-commits at lists.llvm.org> wrote:
> >>
> >> Author: d0k
> >> Date: Sat Aug 20 11:51:33 2016
> >> New Revision: 279374
> >>
> >> URL: http://llvm.org/viewvc/llvm-project?rev=279374&view=rev
> >> Log:
> >> [Sema] Don't crash on scanf on forward-declared enums.
> >>
> >> This is valid in GNU C, which allows pointers to incomplete enums. GCC
> >> just pretends that the underlying type is 'int' in those cases, follow
> >> that behavior.
> >>
> >> Modified:
> >> cfe/trunk/lib/Analysis/FormatString.cpp
> >> cfe/trunk/lib/Analysis/ScanfFormatString.cpp
> >> cfe/trunk/test/Sema/format-strings-enum.c
> >>
> >> Modified: cfe/trunk/lib/Analysis/FormatString.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/FormatString.cpp?rev=279374&r1=279373&r2=279374&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/Analysis/FormatString.cpp (original)
> >> +++ cfe/trunk/lib/Analysis/FormatString.cpp Sat Aug 20 11:51:33 2016
> >> @@ -310,8 +310,13 @@ ArgType::matchesType(ASTContext &C, Qual
> >> return Match;
> >>
> >> case AnyCharTy: {
> >> - if (const EnumType *ETy = argTy->getAs<EnumType>())
> >> + if (const EnumType *ETy = argTy->getAs<EnumType>()) {
> >> + // If the enum is incomplete we know nothing about the
> underlying
> >> type.
> >> + // Assume that it's 'int'.
> >> + if (!ETy->getDecl()->isComplete())
> >> + return NoMatch;
> >> argTy = ETy->getDecl()->getIntegerType();
> >> + }
> >>
> >> if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
> >> switch (BT->getKind()) {
> >> @@ -327,8 +332,14 @@ ArgType::matchesType(ASTContext &C, Qual
> >> }
> >>
> >> case SpecificTy: {
> >> - if (const EnumType *ETy = argTy->getAs<EnumType>())
> >> - argTy = ETy->getDecl()->getIntegerType();
> >> + if (const EnumType *ETy = argTy->getAs<EnumType>()) {
> >> + // If the enum is incomplete we know nothing about the
> underlying
> >> type.
> >> + // Assume that it's 'int'.
> >> + if (!ETy->getDecl()->isComplete())
> >> + argTy = C.IntTy;
> >> + else
> >> + argTy = ETy->getDecl()->getIntegerType();
> >> + }
> >> argTy = C.getCanonicalType(argTy).getUnqualifiedType();
> >>
> >> if (T == argTy)
> >>
> >> Modified: cfe/trunk/lib/Analysis/ScanfFormatString.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ScanfFormatString.cpp?rev=279374&r1=279373&r2=279374&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/Analysis/ScanfFormatString.cpp (original)
> >> +++ cfe/trunk/lib/Analysis/ScanfFormatString.cpp Sat Aug 20 11:51:33
> 2016
> >> @@ -418,8 +418,12 @@ bool ScanfSpecifier::fixType(QualType QT
> >> QualType PT = QT->getPointeeType();
> >>
> >> // If it's an enum, get its underlying type.
> >> - if (const EnumType *ETy = PT->getAs<EnumType>())
> >> + if (const EnumType *ETy = PT->getAs<EnumType>()) {
> >> + // Don't try to fix incomplete enums.
> >> + if (!ETy->getDecl()->isComplete())
> >> + return false;
> >> PT = ETy->getDecl()->getIntegerType();
> >> + }
> >>
> >> const BuiltinType *BT = PT->getAs<BuiltinType>();
> >> if (!BT)
> >>
> >> Modified: cfe/trunk/test/Sema/format-strings-enum.c
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings-enum.c?rev=279374&r1=279373&r2=279374&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/test/Sema/format-strings-enum.c (original)
> >> +++ cfe/trunk/test/Sema/format-strings-enum.c Sat Aug 20 11:51:33 2016
> >> @@ -11,6 +11,7 @@
> >> #endif
> >>
> >> EXTERN_C int printf(const char *,...);
> >> +EXTERN_C int scanf(const char *, ...);
> >>
> >> typedef enum { Constant = 0 } TestEnum;
> >> // Note that in C, the type of 'Constant' is 'int'. In C++ it is
> >> 'TestEnum'.
> >> @@ -34,3 +35,18 @@ void testLong(LongEnum input) {
> >> printf("%lu", input);
> >> printf("%lu", LongConstant);
> >> }
> >> +
> >> +#ifndef __cplusplus
> >> +// GNU C allows forward declaring enums.
> >> +extern enum forward_declared *fwd;
> >> +
> >> +void forward_enum() {
> >> + printf("%u", fwd); // expected-warning{{format specifies type
> 'unsigned
> >> int' but the argument has type 'enum forward_declared *}}
> >> + printf("%p", fwd);
> >> +
> >> + scanf("%c", fwd); // expected-warning{{format specifies type 'char *'
> >> but the argument has type 'enum forward_declared *}}
> >> + scanf("%u", fwd);
> >> + scanf("%lu", fwd); // expected-warning{{format specifies type
> 'unsigned
> >> long *' but the argument has type 'enum forward_declared *}}
> >> + scanf("%p", fwd); // expected-warning{{format specifies type 'void
> **'
> >> but the argument has type 'enum forward_declared *}}
> >> +}
> >> +#endif
> >>
> >>
> >> _______________________________________________
> >> cfe-commits mailing list
> >> cfe-commits at lists.llvm.org
> >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160822/41642e31/attachment.html>
More information about the cfe-commits
mailing list