[cfe-commits] r146326 - in /cfe/trunk: include/clang/Analysis/Analyses/FormatString.h lib/Analysis/ScanfFormatString.cpp lib/Sema/SemaChecking.cpp test/Analysis/taint-generic.c test/Analysis/taint-tester.c test/Sema/format-strings-fixit.c test/Sema/format-strings-int-typedefs.c test/Sema/format-strings-scanf.c

jahanian fjahanian at apple.com
Tue Dec 13 10:59:43 PST 2011


On Dec 13, 2011, at 10:46 AM, Eric Christopher wrote:

> *nod* Fariborz generally looks at those, Fariborz? Hans? Thoughts on the error messages?
> 
> -eric
> 
> On Dec 12, 2011, at 10:47 PM, Ted Kremenek wrote:
> 
>> It is also possible that those tests need to be modified if Clang's behavior ends up being more desirable than what is reflected in those tests.  I haven't looked at them, so I don't know off hand.
>> 
>> On Dec 12, 2011, at 11:01 AM, Peter Cooper wrote:
>> 
>>> Hi Hans
>>> 
>>> We're getting some buildbot errors after this change when running some gcc tests.
>>> 
>>> The tests in question are:
>>> 
>>> gcc.dg/format/c90-scanf-3.c   (test for excess errors)
>>> gcc.dg/format/c90-scanf-3.c  -DWIDE  (test for excess errors)

Tests, according to gcc should diagnose as:
c90-scanf-3.c:16: warning: ISO C does not support the 'a' scanf flag
etc. clang ignores -std=iso9899:1990 flag.

>>> gcc.dg/format/ext-4.c   (test for excess errors)
>>> gcc.dg/format/ext-4.c  -DWIDE  (test for excess errors)
gcc expects tests to compile with no warning (probably due to use of -std=gnu89).

Generally, for irrelevant tests (or for future considerations), we move the tests to 
gcc-4_2-testsuite/ignored directory (or make them expected failure). 
Moving to gcc-4_2-testsuite/ignored is preferred because we frequently revisit them,

- Fariborz


>>> Can you please take a look at how you want your fix to interact with the -pedantic warnings on those tests?
>>> 
>>> Oh, and shouldn't make much difference as those are front-end tests but this is on x86-64 darwin.
>>> 
>>> Thanks,
>>> Pete
>>> 
>>> On Dec 10, 2011, at 5:20 AM, Hans Wennborg wrote:
>>> 
>>>> Author: hans
>>>> Date: Sat Dec 10 07:20:11 2011
>>>> New Revision: 146326
>>>> 
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=146326&view=rev
>>>> Log:
>>>> Check that arguments to a scanf call match the format specifier,
>>>> and offer fixits when there is a mismatch.
>>>> 
>>>> Modified:
>>>>    cfe/trunk/include/clang/Analysis/Analyses/FormatString.h
>>>>    cfe/trunk/lib/Analysis/ScanfFormatString.cpp
>>>>    cfe/trunk/lib/Sema/SemaChecking.cpp
>>>>    cfe/trunk/test/Analysis/taint-generic.c
>>>>    cfe/trunk/test/Analysis/taint-tester.c
>>>>    cfe/trunk/test/Sema/format-strings-fixit.c
>>>>    cfe/trunk/test/Sema/format-strings-int-typedefs.c
>>>>    cfe/trunk/test/Sema/format-strings-scanf.c
>>>> 
>>>> Modified: cfe/trunk/include/clang/Analysis/Analyses/FormatString.h
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/FormatString.h?rev=146326&r1=146325&r2=146326&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/include/clang/Analysis/Analyses/FormatString.h (original)
>>>> +++ cfe/trunk/include/clang/Analysis/Analyses/FormatString.h Sat Dec 10 07:20:11 2011
>>>> @@ -185,6 +185,7 @@
>>>>     return EndScanList ? EndScanList - Position : 1;
>>>>   }
>>>> 
>>>> +  bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; }
>>>>   const char *toString() const;
>>>> 
>>>>   bool isPrintfKind() const { return IsPrintf; }
>>>> @@ -364,7 +365,6 @@
>>>> 
>>>>   bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; }
>>>>   bool isIntArg() const { return kind >= IntArgBeg && kind <= IntArgEnd; }
>>>> -  bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; }
>>>>   bool isDoubleArg() const { return kind >= DoubleArgBeg &&
>>>>                                     kind <= DoubleArgBeg; }
>>>>   unsigned getLength() const {
>>>> @@ -506,10 +506,35 @@
>>>>   }
>>>> };
>>>> 
>>>> +using analyze_format_string::ArgTypeResult;
>>>> using analyze_format_string::LengthModifier;
>>>> using analyze_format_string::OptionalAmount;
>>>> using analyze_format_string::OptionalFlag;
>>>> 
>>>> +class ScanfArgTypeResult : public ArgTypeResult {
>>>> +public:
>>>> +  enum Kind { UnknownTy, InvalidTy, CStrTy, WCStrTy, PtrToArgTypeResultTy };
>>>> +private:
>>>> +  Kind K;
>>>> +  ArgTypeResult A;
>>>> +  const char *Name;
>>>> +  QualType getRepresentativeType(ASTContext &C) const;
>>>> +public:
>>>> +  ScanfArgTypeResult(Kind k = UnknownTy, const char* n = 0) : K(k), Name(n) {}
>>>> +  ScanfArgTypeResult(ArgTypeResult a, const char *n = 0)
>>>> +      : K(PtrToArgTypeResultTy), A(a), Name(n) {
>>>> +    assert(A.isValid());
>>>> +  }
>>>> +
>>>> +  static ScanfArgTypeResult Invalid() { return ScanfArgTypeResult(InvalidTy); }
>>>> +
>>>> +  bool isValid() const { return K != InvalidTy; }
>>>> +
>>>> +  bool matchesType(ASTContext& C, QualType argTy) const;
>>>> +
>>>> +  std::string getRepresentativeTypeName(ASTContext& C) const;
>>>> +};
>>>> +
>>>> class ScanfSpecifier : public analyze_format_string::FormatSpecifier {
>>>>   OptionalFlag SuppressAssignment; // '*'
>>>> public:
>>>> @@ -538,6 +563,12 @@
>>>>     return CS.consumesDataArgument() && !SuppressAssignment;
>>>>   }
>>>> 
>>>> +  ScanfArgTypeResult getArgType(ASTContext &Ctx) const;
>>>> +
>>>> +  bool fixType(QualType QT, const LangOptions &LangOpt);
>>>> +
>>>> +  void toString(raw_ostream &os) const;
>>>> +
>>>>   static ScanfSpecifier Parse(const char *beg, const char *end);
>>>> };
>>>> 
>>>> 
>>>> Modified: cfe/trunk/lib/Analysis/ScanfFormatString.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ScanfFormatString.cpp?rev=146326&r1=146325&r2=146326&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Analysis/ScanfFormatString.cpp (original)
>>>> +++ cfe/trunk/lib/Analysis/ScanfFormatString.cpp Sat Dec 10 07:20:11 2011
>>>> @@ -20,9 +20,11 @@
>>>> using clang::analyze_format_string::LengthModifier;
>>>> using clang::analyze_format_string::OptionalAmount;
>>>> using clang::analyze_format_string::ConversionSpecifier;
>>>> +using clang::analyze_scanf::ScanfArgTypeResult;
>>>> using clang::analyze_scanf::ScanfConversionSpecifier;
>>>> using clang::analyze_scanf::ScanfSpecifier;
>>>> using clang::UpdateOnReturn;
>>>> +using namespace clang;
>>>> 
>>>> typedef clang::analyze_format_string::SpecifierResult<ScanfSpecifier>
>>>>         ScanfSpecifierResult;
>>>> @@ -190,7 +192,213 @@
>>>>   }
>>>>   return ScanfSpecifierResult(Start, FS);
>>>> }
>>>> -  
>>>> +
>>>> +ScanfArgTypeResult ScanfSpecifier::getArgType(ASTContext &Ctx) const {
>>>> +  const ScanfConversionSpecifier &CS = getConversionSpecifier();
>>>> +
>>>> +  if (!CS.consumesDataArgument())
>>>> +    return ScanfArgTypeResult::Invalid();
>>>> +
>>>> +  switch(CS.getKind()) {
>>>> +    // Signed int.
>>>> +    case ConversionSpecifier::dArg:
>>>> +    case ConversionSpecifier::iArg:
>>>> +      switch (LM.getKind()) {
>>>> +        case LengthModifier::None: return ArgTypeResult(Ctx.IntTy);
>>>> +        case LengthModifier::AsChar:
>>>> +          return ArgTypeResult(ArgTypeResult::AnyCharTy);
>>>> +        case LengthModifier::AsShort: return ArgTypeResult(Ctx.ShortTy);
>>>> +        case LengthModifier::AsLong: return ArgTypeResult(Ctx.LongTy);
>>>> +        case LengthModifier::AsLongLong: return ArgTypeResult(Ctx.LongLongTy);
>>>> +        case LengthModifier::AsIntMax:
>>>> +          return ScanfArgTypeResult(Ctx.getIntMaxType(), "intmax_t *");
>>>> +        case LengthModifier::AsSizeT:
>>>> +          // FIXME: ssize_t.
>>>> +          return ScanfArgTypeResult();
>>>> +        case LengthModifier::AsPtrDiff:
>>>> +          return ScanfArgTypeResult(Ctx.getPointerDiffType(), "ptrdiff_t *");
>>>> +        case LengthModifier::AsLongDouble: return ScanfArgTypeResult::Invalid();
>>>> +      }
>>>> +
>>>> +    // Unsigned int.
>>>> +    case ConversionSpecifier::oArg:
>>>> +    case ConversionSpecifier::uArg:
>>>> +    case ConversionSpecifier::xArg:
>>>> +    case ConversionSpecifier::XArg:
>>>> +      switch (LM.getKind()) {
>>>> +        case LengthModifier::None: return ArgTypeResult(Ctx.UnsignedIntTy);
>>>> +        case LengthModifier::AsChar: return ArgTypeResult(Ctx.UnsignedCharTy);
>>>> +        case LengthModifier::AsShort: return ArgTypeResult(Ctx.UnsignedShortTy);
>>>> +        case LengthModifier::AsLong: return ArgTypeResult(Ctx.UnsignedLongTy);
>>>> +        case LengthModifier::AsLongLong:
>>>> +          return ArgTypeResult(Ctx.UnsignedLongLongTy);
>>>> +        case LengthModifier::AsIntMax:
>>>> +          return ScanfArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t *");
>>>> +        case LengthModifier::AsSizeT:
>>>> +          return ScanfArgTypeResult(Ctx.getSizeType(), "size_t *");
>>>> +        case LengthModifier::AsPtrDiff:
>>>> +          // FIXME: Unsigned version of ptrdiff_t?
>>>> +          return ScanfArgTypeResult();
>>>> +        case LengthModifier::AsLongDouble: return ScanfArgTypeResult::Invalid();
>>>> +      }
>>>> +
>>>> +    // Float.
>>>> +    case ConversionSpecifier::aArg:
>>>> +    case ConversionSpecifier::AArg:
>>>> +    case ConversionSpecifier::eArg:
>>>> +    case ConversionSpecifier::EArg:
>>>> +    case ConversionSpecifier::fArg:
>>>> +    case ConversionSpecifier::FArg:
>>>> +    case ConversionSpecifier::gArg:
>>>> +    case ConversionSpecifier::GArg:
>>>> +      switch (LM.getKind()) {
>>>> +        case LengthModifier::None: return ArgTypeResult(Ctx.FloatTy);
>>>> +        case LengthModifier::AsLong: return ArgTypeResult(Ctx.DoubleTy);
>>>> +        case LengthModifier::AsLongDouble:
>>>> +          return ArgTypeResult(Ctx.LongDoubleTy);
>>>> +        default:
>>>> +          return ScanfArgTypeResult::Invalid();
>>>> +      }
>>>> +
>>>> +    // Char, string and scanlist.
>>>> +    case ConversionSpecifier::cArg:
>>>> +    case ConversionSpecifier::sArg:
>>>> +    case ConversionSpecifier::ScanListArg:
>>>> +      switch (LM.getKind()) {
>>>> +        case LengthModifier::None: return ScanfArgTypeResult::CStrTy;
>>>> +        case LengthModifier::AsLong:
>>>> +          return ScanfArgTypeResult(ScanfArgTypeResult::WCStrTy, "wchar_t *");
>>>> +        default:
>>>> +          return ScanfArgTypeResult::Invalid();
>>>> +      }
>>>> +    case ConversionSpecifier::CArg:
>>>> +    case ConversionSpecifier::SArg:
>>>> +      // FIXME: Mac OS X specific?
>>>> +      return ScanfArgTypeResult(ScanfArgTypeResult::WCStrTy, "wchar_t *");
>>>> +
>>>> +    // Pointer.
>>>> +    case ConversionSpecifier::pArg:
>>>> +      return ScanfArgTypeResult(ArgTypeResult(ArgTypeResult::CPointerTy));
>>>> +
>>>> +    default:
>>>> +      break;
>>>> +  }
>>>> +
>>>> +  return ScanfArgTypeResult();
>>>> +}
>>>> +
>>>> +bool ScanfSpecifier::fixType(QualType QT, const LangOptions &LangOpt)
>>>> +{
>>>> +  if (!QT->isPointerType())
>>>> +    return false;
>>>> +
>>>> +  QualType PT = QT->getPointeeType();
>>>> +  const BuiltinType *BT = PT->getAs<BuiltinType>();
>>>> +  if (!BT)
>>>> +    return false;
>>>> +
>>>> +  // Pointer to a character.
>>>> +  if (PT->isAnyCharacterType()) {
>>>> +    CS.setKind(ConversionSpecifier::sArg);
>>>> +    if (PT->isWideCharType())
>>>> +      LM.setKind(LengthModifier::AsWideChar);
>>>> +    else
>>>> +      LM.setKind(LengthModifier::None);
>>>> +    return true;
>>>> +  }
>>>> +
>>>> +  // Figure out the length modifier.
>>>> +  switch (BT->getKind()) {
>>>> +    // no modifier
>>>> +    case BuiltinType::UInt:
>>>> +    case BuiltinType::Int:
>>>> +    case BuiltinType::Float:
>>>> +      LM.setKind(LengthModifier::None);
>>>> +      break;
>>>> +
>>>> +    // hh
>>>> +    case BuiltinType::Char_U:
>>>> +    case BuiltinType::UChar:
>>>> +    case BuiltinType::Char_S:
>>>> +    case BuiltinType::SChar:
>>>> +      LM.setKind(LengthModifier::AsChar);
>>>> +      break;
>>>> +
>>>> +    // h
>>>> +    case BuiltinType::Short:
>>>> +    case BuiltinType::UShort:
>>>> +      LM.setKind(LengthModifier::AsShort);
>>>> +      break;
>>>> +
>>>> +    // l
>>>> +    case BuiltinType::Long:
>>>> +    case BuiltinType::ULong:
>>>> +    case BuiltinType::Double:
>>>> +      LM.setKind(LengthModifier::AsLong);
>>>> +      break;
>>>> +
>>>> +    // ll
>>>> +    case BuiltinType::LongLong:
>>>> +    case BuiltinType::ULongLong:
>>>> +      LM.setKind(LengthModifier::AsLongLong);
>>>> +      break;
>>>> +
>>>> +    // L
>>>> +    case BuiltinType::LongDouble:
>>>> +      LM.setKind(LengthModifier::AsLongDouble);
>>>> +      break;
>>>> +
>>>> +    // Don't know.
>>>> +    default:
>>>> +      return false;
>>>> +  }
>>>> +
>>>> +  // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
>>>> +  if (isa<TypedefType>(PT) && (LangOpt.C99 || LangOpt.CPlusPlus0x)) {
>>>> +    const IdentifierInfo *Identifier = QT.getBaseTypeIdentifier();
>>>> +    if (Identifier->getName() == "size_t") {
>>>> +      LM.setKind(LengthModifier::AsSizeT);
>>>> +    } else if (Identifier->getName() == "ssize_t") {
>>>> +      // Not C99, but common in Unix.
>>>> +      LM.setKind(LengthModifier::AsSizeT);
>>>> +    } else if (Identifier->getName() == "intmax_t") {
>>>> +      LM.setKind(LengthModifier::AsIntMax);
>>>> +    } else if (Identifier->getName() == "uintmax_t") {
>>>> +      LM.setKind(LengthModifier::AsIntMax);
>>>> +    } else if (Identifier->getName() == "ptrdiff_t") {
>>>> +      LM.setKind(LengthModifier::AsPtrDiff);
>>>> +    }
>>>> +  }
>>>> +
>>>> +  // Figure out the conversion specifier.
>>>> +  if (PT->isRealFloatingType())
>>>> +    CS.setKind(ConversionSpecifier::fArg);
>>>> +  else if (PT->isSignedIntegerType())
>>>> +    CS.setKind(ConversionSpecifier::dArg);
>>>> +  else if (PT->isUnsignedIntegerType()) {
>>>> +    // Preserve the original formatting, e.g. 'X', 'o'.
>>>> +    if (!CS.isUIntArg()) {
>>>> +      CS.setKind(ConversionSpecifier::uArg);
>>>> +    }
>>>> +  } else
>>>> +    llvm_unreachable("Unexpected type");
>>>> +
>>>> +  return true;
>>>> +}
>>>> +
>>>> +void ScanfSpecifier::toString(raw_ostream &os) const {
>>>> +  os << "%";
>>>> +
>>>> +  if (usesPositionalArg())
>>>> +    os << getPositionalArgIndex() << "$";
>>>> +  if (SuppressAssignment)
>>>> +    os << "*";
>>>> +
>>>> +  FieldWidth.toString(os);
>>>> +  os << LM.toString();
>>>> +  os << CS.toString();
>>>> +}
>>>> +
>>>> bool clang::analyze_format_string::ParseScanfString(FormatStringHandler &H,
>>>>                                                     const char *I,
>>>>                                                     const char *E) {
>>>> @@ -218,4 +426,47 @@
>>>>   return false;
>>>> }
>>>> 
>>>> +bool ScanfArgTypeResult::matchesType(ASTContext& C, QualType argTy) const {
>>>> +  switch (K) {
>>>> +    case InvalidTy:
>>>> +      llvm_unreachable("ArgTypeResult must be valid");
>>>> +    case UnknownTy:
>>>> +      return true;
>>>> +    case CStrTy:
>>>> +      return ArgTypeResult(ArgTypeResult::CStrTy).matchesType(C, argTy);
>>>> +    case WCStrTy:
>>>> +      return ArgTypeResult(ArgTypeResult::WCStrTy).matchesType(C, argTy);
>>>> +    case PtrToArgTypeResultTy: {
>>>> +      const PointerType *PT = argTy->getAs<PointerType>();
>>>> +      if (!PT)
>>>> +        return false;
>>>> +      return A.matchesType(C, PT->getPointeeType());
>>>> +    }
>>>> +  }
>>>> 
>>>> +  return false; // Unreachable, but we still get a warning.
>>>> +}
>>>> +
>>>> +QualType ScanfArgTypeResult::getRepresentativeType(ASTContext &C) const {
>>>> +  switch (K) {
>>>> +    case InvalidTy:
>>>> +      llvm_unreachable("No representative type for Invalid ArgTypeResult");
>>>> +    case UnknownTy:
>>>> +      return QualType();
>>>> +    case CStrTy:
>>>> +      return C.getPointerType(C.CharTy);
>>>> +    case WCStrTy:
>>>> +      return C.getPointerType(C.getWCharType());
>>>> +    case PtrToArgTypeResultTy:
>>>> +      return C.getPointerType(A.getRepresentativeType(C));
>>>> +  }
>>>> +
>>>> +  return QualType(); // Not reachable.
>>>> +}
>>>> +
>>>> +std::string ScanfArgTypeResult::getRepresentativeTypeName(ASTContext& C) const {
>>>> +  std::string S = getRepresentativeType(C).getAsString();
>>>> +  if (!Name)
>>>> +    return std::string("'") + S + "'";
>>>> +  return std::string("'") + Name + "' (aka '" + S + "')";
>>>> +}
>>>> 
>>>> Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=146326&r1=146325&r2=146326&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
>>>> +++ cfe/trunk/lib/Sema/SemaChecking.cpp Sat Dec 10 07:20:11 2011
>>>> @@ -2371,8 +2371,38 @@
>>>>   if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
>>>>     return false;
>>>> 
>>>> -  // FIXME: Check that the argument type matches the format specifier.
>>>> -  
>>>> +  // Check that the argument type matches the format specifier.
>>>> +  const Expr *Ex = getDataArg(argIndex);
>>>> +  const analyze_scanf::ScanfArgTypeResult &ATR = FS.getArgType(S.Context);
>>>> +  if (ATR.isValid() && !ATR.matchesType(S.Context, Ex->getType())) {
>>>> +    ScanfSpecifier fixedFS = FS;
>>>> +    bool success = fixedFS.fixType(Ex->getType(), S.getLangOptions());
>>>> +
>>>> +    if (success) {
>>>> +      // Get the fix string from the fixed format specifier.
>>>> +      llvm::SmallString<128> buf;
>>>> +      llvm::raw_svector_ostream os(buf);
>>>> +      fixedFS.toString(os);
>>>> +
>>>> +      EmitFormatDiagnostic(
>>>> +        S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
>>>> +          << ATR.getRepresentativeTypeName(S.Context) << Ex->getType()
>>>> +          << Ex->getSourceRange(),
>>>> +        getLocationOfByte(CS.getStart()),
>>>> +        /*IsStringLocation*/true,
>>>> +        getSpecifierRange(startSpecifier, specifierLen),
>>>> +        FixItHint::CreateReplacement(
>>>> +          getSpecifierRange(startSpecifier, specifierLen),
>>>> +          os.str()));
>>>> +    } else {
>>>> +      S.Diag(getLocationOfByte(CS.getStart()),
>>>> +             diag::warn_printf_conversion_argument_type_mismatch)
>>>> +          << ATR.getRepresentativeTypeName(S.Context) << Ex->getType()
>>>> +          << getSpecifierRange(startSpecifier, specifierLen)
>>>> +          << Ex->getSourceRange();
>>>> +    }
>>>> +  }
>>>> +
>>>>   return true;
>>>> }
>>>> 
>>>> 
>>>> Modified: cfe/trunk/test/Analysis/taint-generic.c
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/taint-generic.c?rev=146326&r1=146325&r2=146326&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/test/Analysis/taint-generic.c (original)
>>>> +++ cfe/trunk/test/Analysis/taint-generic.c Sat Dec 10 07:20:11 2011
>>>> @@ -39,7 +39,8 @@
>>>> 
>>>> void scanfArg() {
>>>>   int t;
>>>> -  scanf("%d", t); // expected-warning {{Pointer argument is expected}}
>>>> +  scanf("%d", t); // expected-warning {{Pointer argument is expected}} \
>>>> +                  // expected-warning {{conversion specifies type 'int *' but the argument has type 'int'}}
>>>> }
>>>> 
>>>> void bufferGetchar(int x) {
>>>> 
>>>> Modified: cfe/trunk/test/Analysis/taint-tester.c
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/taint-tester.c?rev=146326&r1=146325&r2=146326&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/test/Analysis/taint-tester.c (original)
>>>> +++ cfe/trunk/test/Analysis/taint-tester.c Sat Dec 10 07:20:11 2011
>>>> @@ -49,8 +49,8 @@
>>>> 
>>>>   // Taint on fields of a struct.
>>>>   struct XYStruct xy = {2, 3, 11};
>>>> -  scanf("%f", &xy.y);
>>>> -  scanf("%f", &xy.x);
>>>> +  scanf("%d", &xy.y);
>>>> +  scanf("%d", &xy.x);
>>>>   int tx = xy.x; // expected-warning {{tainted}}
>>>>   int ty = xy.y; // FIXME: This should be tainted as well.
>>>>   char ntz = xy.z;// no warning
>>>> 
>>>> Modified: cfe/trunk/test/Sema/format-strings-fixit.c
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings-fixit.c?rev=146326&r1=146325&r2=146326&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/test/Sema/format-strings-fixit.c (original)
>>>> +++ cfe/trunk/test/Sema/format-strings-fixit.c Sat Dec 10 07:20:11 2011
>>>> @@ -10,6 +10,11 @@
>>>> 
>>>> int printf(char const *, ...);
>>>> 
>>>> +typedef __SIZE_TYPE__ size_t;
>>>> +typedef __INTMAX_TYPE__ intmax_t;
>>>> +typedef __UINTMAX_TYPE__ uintmax_t;
>>>> +typedef __PTRDIFF_TYPE__ ptrdiff_t;
>>>> +
>>>> void test() {
>>>>   // Basic types
>>>>   printf("%s", (int) 123);
>>>> @@ -47,11 +52,6 @@
>>>>   unsigned long val = 42;
>>>>   printf("%X", val);
>>>> 
>>>> -  typedef __SIZE_TYPE__ size_t;
>>>> -  typedef __INTMAX_TYPE__ intmax_t;
>>>> -  typedef __UINTMAX_TYPE__ uintmax_t;
>>>> -  typedef __PTRDIFF_TYPE__ ptrdiff_t;
>>>> -
>>>>   // size_t, etc.
>>>>   printf("%f", (size_t) 42);
>>>>   printf("%f", (intmax_t) 42);
>>>> @@ -62,6 +62,51 @@
>>>>   printf("%ld", "foo");
>>>> }
>>>> 
>>>> +int scanf(char const *, ...);
>>>> +
>>>> +void test2() {
>>>> +  char str[100];
>>>> +  short shortVar;
>>>> +  unsigned short uShortVar;
>>>> +  int intVar;
>>>> +  unsigned uIntVar;
>>>> +  float floatVar;
>>>> +  double doubleVar;
>>>> +  long double longDoubleVar;
>>>> +  long longVar;
>>>> +  unsigned long uLongVar;
>>>> +  long long longLongVar;
>>>> +  unsigned long long uLongLongVar;
>>>> +  size_t sizeVar;
>>>> +  intmax_t intmaxVar;
>>>> +  uintmax_t uIntmaxVar;
>>>> +  ptrdiff_t ptrdiffVar;
>>>> +
>>>> +  scanf("%lf", str);
>>>> +  scanf("%f", &shortVar);
>>>> +  scanf("%f", &uShortVar);
>>>> +  scanf("%p", &intVar);
>>>> +  scanf("%Lf", &uIntVar);
>>>> +  scanf("%ld", &floatVar);
>>>> +  scanf("%f", &doubleVar);
>>>> +  scanf("%d", &longDoubleVar);
>>>> +  scanf("%f", &longVar);
>>>> +  scanf("%f", &uLongVar);
>>>> +  scanf("%f", &longLongVar);
>>>> +  scanf("%f", &uLongLongVar);
>>>> +
>>>> +  // Some named ints.
>>>> +  scanf("%f", &sizeVar);
>>>> +  scanf("%f", &intmaxVar);
>>>> +  scanf("%f", &uIntmaxVar);
>>>> +  scanf("%f", &ptrdiffVar);
>>>> +
>>>> +  // Perserve the original formatting for unsigned integers.
>>>> +  scanf("%o", &uLongVar);
>>>> +  scanf("%x", &uLongVar);
>>>> +  scanf("%X", &uLongVar);
>>>> +}
>>>> +
>>>> // Validate the fixes...
>>>> // CHECK: printf("%d", (int) 123);
>>>> // CHECK: printf("abc%s", "testing testing 123");
>>>> @@ -87,3 +132,23 @@
>>>> // CHECK: printf("%ju", (uintmax_t) 42);
>>>> // CHECK: printf("%td", (ptrdiff_t) 42);
>>>> // CHECK: printf("%s", "foo");
>>>> +
>>>> +// CHECK: scanf("%s", str);
>>>> +// CHECK: scanf("%hd", &shortVar);
>>>> +// CHECK: scanf("%hu", &uShortVar);
>>>> +// CHECK: scanf("%d", &intVar);
>>>> +// CHECK: scanf("%u", &uIntVar);
>>>> +// CHECK: scanf("%f", &floatVar);
>>>> +// CHECK: scanf("%lf", &doubleVar);
>>>> +// CHECK: scanf("%Lf", &longDoubleVar);
>>>> +// CHECK: scanf("%ld", &longVar);
>>>> +// CHECK: scanf("%lu", &uLongVar);
>>>> +// CHECK: scanf("%lld", &longLongVar);
>>>> +// CHECK: scanf("%llu", &uLongLongVar);
>>>> +// CHECK: scanf("%zu", &sizeVar);
>>>> +// CHECK: scanf("%jd", &intmaxVar);
>>>> +// CHECK: scanf("%ju", &uIntmaxVar);
>>>> +// CHECK: scanf("%td", &ptrdiffVar);
>>>> +// CHECK: scanf("%lo", &uLongVar);
>>>> +// CHECK: scanf("%lx", &uLongVar);
>>>> +// CHECK: scanf("%lX", &uLongVar);
>>>> 
>>>> Modified: cfe/trunk/test/Sema/format-strings-int-typedefs.c
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings-int-typedefs.c?rev=146326&r1=146325&r2=146326&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/test/Sema/format-strings-int-typedefs.c (original)
>>>> +++ cfe/trunk/test/Sema/format-strings-int-typedefs.c Sat Dec 10 07:20:11 2011
>>>> @@ -1,6 +1,7 @@
>>>> // RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
>>>> 
>>>> int printf(char const *, ...);
>>>> +int scanf(char const *, ...);
>>>> 
>>>> void test(void) {
>>>>   printf("%jd", 42.0); // expected-warning {{conversion specifies type 'intmax_t' (aka 'long long')}}
>>>> @@ -12,6 +13,15 @@
>>>>   printf("%S", 42.0);  // expected-warning {{conversion specifies type 'wchar_t *' (aka 'int *')}}
>>>>   printf("%C", 42.0);  // expected-warning {{conversion specifies type 'wchar_t' (aka 'int')}}
>>>> 
>>>> +  scanf("%jd", 0); // expected-warning {{conversion specifies type 'intmax_t *' (aka 'long long *')}}
>>>> +  scanf("%ju", 0); // expected-warning {{conversion specifies type 'uintmax_t *' (aka 'unsigned long long *')}}
>>>> +  scanf("%zu", 0); // expected-warning {{conversion specifies type 'size_t *' (aka 'unsigned long *')}}
>>>> +  scanf("%td", 0); // expected-warning {{conversion specifies type 'ptrdiff_t *' (aka 'int *')}}
>>>> +  scanf("%lc", 0); // expected-warning {{conversion specifies type 'wchar_t *' (aka 'int *')}}
>>>> +  scanf("%ls", 0); // expected-warning {{conversion specifies type 'wchar_t *' (aka 'int *')}}
>>>> +  scanf("%S",  0);  // expected-warning {{conversion specifies type 'wchar_t *' (aka 'int *')}}
>>>> +  scanf("%C",  0);  // expected-warning {{conversion specifies type 'wchar_t *' (aka 'int *')}}
>>>> +
>>>> 
>>>>   // typedef size_t et al. to something crazy.
>>>>   typedef void *size_t;
>>>> 
>>>> Modified: cfe/trunk/test/Sema/format-strings-scanf.c
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings-scanf.c?rev=146326&r1=146325&r2=146326&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/test/Sema/format-strings-scanf.c (original)
>>>> +++ cfe/trunk/test/Sema/format-strings-scanf.c Sat Dec 10 07:20:11 2011
>>>> @@ -28,7 +28,7 @@
>>>> 
>>>> void bad_length_modifiers(char *s, void *p, wchar_t *ws, long double *ld) {
>>>>   scanf("%hhs", "foo"); // expected-warning{{length modifier 'hh' results in undefined behavior or no effect with 's' conversion specifier}}
>>>> -  scanf("%1$zp", p); // expected-warning{{length modifier 'z' results in undefined behavior or no effect with 'p' conversion specifier}}
>>>> +  scanf("%1$zp", &p); // expected-warning{{length modifier 'z' results in undefined behavior or no effect with 'p' conversion specifier}}
>>>>   scanf("%ls", ws); // no-warning
>>>>   scanf("%#.2Lf", ld); // expected-warning{{invalid conversion specifier '#'}}
>>>> }
>>>> @@ -37,10 +37,11 @@
>>>> // format string is somewhere else, point to it in a note.
>>>> void pr9751() {
>>>>   int *i;
>>>> +  char str[100];
>>>>   const char kFormat1[] = "%00d"; // expected-note{{format string is defined here}}}
>>>>   scanf(kFormat1, i); // expected-warning{{zero field width in scanf format string is unused}}
>>>>   scanf("%00d", i); // expected-warning{{zero field width in scanf format string is unused}}
>>>>   const char kFormat2[] = "%["; // expected-note{{format string is defined here}}}
>>>> -  scanf(kFormat2, &i); // expected-warning{{no closing ']' for '%[' in scanf format string}}
>>>> -  scanf("%[", &i); // expected-warning{{no closing ']' for '%[' in scanf format string}}
>>>> +  scanf(kFormat2, str); // expected-warning{{no closing ']' for '%[' in scanf format string}}
>>>> +  scanf("%[", str); // expected-warning{{no closing ']' for '%[' in scanf format string}}
>>>> }
>>>> 
>>>> 
>>>> _______________________________________________
>>>> cfe-commits mailing list
>>>> cfe-commits at cs.uiuc.edu
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>> 
>>> _______________________________________________
>>> cfe-commits mailing list
>>> cfe-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>> 
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20111213/b5d6337e/attachment.html>


More information about the cfe-commits mailing list