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