diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index abe29d2..0d49f05 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -1443,14 +1443,23 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, Expr **Args,
       //      vprintf(fmt, ap);  // Do NOT emit a warning about "fmt".
       //      ...
       //
-      //
-      //  FIXME: We don't have full attribute support yet, so just check to see
-      //    if the argument is a DeclRefExpr that references a parameter.  We'll
-      //    add proper support for checking the attribute later.
       if (HasVAListArg)
-        if (isa<ParmVarDecl>(VD))
+        if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(VD)) {
+          if (const NamedDecl *ND = dyn_cast<NamedDecl>(PV->getDeclContext())) {
+            int PVIndex = PV->getFunctionScopeIndex() + 1;
+            for (specific_attr_iterator<FormatAttr>
+                 i = ND->specific_attr_begin<FormatAttr>(),
+                 e = ND->specific_attr_end<FormatAttr>(); i != e ; ++i) {
+              FormatAttr *Format = *i;
+              // We also check if the format matches.
+              // We can't pass a scanf string to a printf function.
+              if (PVIndex == Format->getFormatIdx() &&
+                  Type == Format->getType())
           return true;
     }
+          }
+        }
+    }
 
     return false;
   }
diff --git a/test/Sema/format-strings.c b/test/Sema/format-strings.c
index 341fd59..c2ebf48 100644
--- a/test/Sema/format-strings.c
+++ b/test/Sema/format-strings.c
@@ -14,6 +14,8 @@ int vprintf(const char *restrict, va_list);
 int vsnprintf(char *, size_t, const char *, va_list);
 int vsprintf(char *restrict, const char *restrict, va_list); // expected-note{{passing argument to parameter here}}
 
+int vscanf(const char *restrict format, va_list arg);
+
 char * global_fmt;
 
 void check_string_literal( FILE* fp, const char* s, char *buf, ... ) {
@@ -23,21 +25,23 @@ void check_string_literal( FILE* fp, const char* s, char *buf, ... ) {
   va_start(ap,buf);
 
   printf(s); // expected-warning {{format string is not a string literal}}
-  vprintf(s,ap); // // no-warning
+  vprintf(s,ap); // expected-warning {{format string is not a string literal}}
   fprintf(fp,s); // expected-warning {{format string is not a string literal}}
-  vfprintf(fp,s,ap); // no-warning
+  vfprintf(fp,s,ap); // expected-warning {{format string is not a string literal}}
   asprintf(&b,s); // expected-warning {{format string is not a string lit}}
-  vasprintf(&b,s,ap); // no-warning
+  vasprintf(&b,s,ap); // expected-warning {{format string is not a string literal}}
   sprintf(buf,s); // expected-warning {{format string is not a string literal}}
   snprintf(buf,2,s); // expected-warning {{format string is not a string lit}}
   __builtin___sprintf_chk(buf,0,-1,s); // expected-warning {{format string is not a string literal}}
   __builtin___snprintf_chk(buf,2,0,-1,s); // expected-warning {{format string is not a string lit}}
-  vsprintf(buf,s,ap); // no-warning
-  vsnprintf(buf,2,s,ap); // no-warning
+  vsprintf(buf,s,ap); // expected-warning {{format string is not a string lit}}
+  vsnprintf(buf,2,s,ap); // expected-warning {{format string is not a string lit}}
   vsnprintf(buf,2,global_fmt,ap); // expected-warning {{format string is not a string literal}}
-  __builtin___vsnprintf_chk(buf,2,0,-1,s,ap); // no-warning
+  __builtin___vsnprintf_chk(buf,2,0,-1,s,ap); // expected-warning {{format string is not a string lit}}
   __builtin___vsnprintf_chk(buf,2,0,-1,global_fmt,ap); // expected-warning {{format string is not a string literal}}
 
+  vscanf(s, ap); // expected-warning {{format string is not a string literal}}
+
   // rdar://6079877
   printf("abc"
          "%*d", 1, 1); // no-warning
@@ -51,6 +55,25 @@ def"
   printf("%*d", (unsigned) 1, 1); // no-warning  
 }
 
+__attribute__((__format__ (__printf__, 2, 4)))
+void check_string_literal2( FILE* fp, const char* s, char *buf, ... ) {
+  char * b;
+  va_list ap;
+  va_start(ap,buf);
+
+  printf(s); // expected-warning {{format string is not a string literal}}
+  vprintf(s,ap); // no-warning
+  fprintf(fp,s); // expected-warning {{format string is not a string literal}}
+  vfprintf(fp,s,ap); // no-warning
+  asprintf(&b,s); // expected-warning {{format string is not a string lit}}
+  vasprintf(&b,s,ap); // no-warning
+  sprintf(buf,s); // expected-warning {{format string is not a string literal}}
+  snprintf(buf,2,s); // expected-warning {{format string is not a string lit}}
+  __builtin___vsnprintf_chk(buf,2,0,-1,s,ap); // no-warning
+
+  vscanf(s, ap); // expected-warning {{format string is not a string literal}}
+}
+
 void check_conditional_literal(const char* s, int i) {
   printf(i == 1 ? "yes" : "no"); // no-warning
   printf(i == 0 ? (i == 1 ? "yes" : "no") : "dont know"); // no-warning
