diff --git a/lib/Analysis/FormatString.cpp b/lib/Analysis/FormatString.cpp
index ab69c06..b5df73a 100644
--- a/lib/Analysis/FormatString.cpp
+++ b/lib/Analysis/FormatString.cpp
@@ -239,9 +239,9 @@ bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const {
 
     case UnknownTy:
       return true;
-      
+
     case AnyCharTy: {
-      if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
+      if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) {
         switch (BT->getKind()) {
           default:
             break;
@@ -249,26 +249,27 @@ bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const {
           case BuiltinType::SChar:
           case BuiltinType::UChar:
           case BuiltinType::Char_U:
-            return true;            
+            return true;
         }
+      }
       return false;
     }
-      
+
     case SpecificTy: {
       argTy = C.getCanonicalType(argTy).getUnqualifiedType();
       if (T == argTy)
         return true;
       // Check for "compatible types".
-      if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
+      if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) {
         switch (BT->getKind()) {
           default:
             break;
           case BuiltinType::Char_S:
           case BuiltinType::SChar:
-            return T == C.UnsignedCharTy;
+            return T == C.SignedCharTy || T == C.UnsignedCharTy;
           case BuiltinType::Char_U:
-          case BuiltinType::UChar:                    
-            return T == C.SignedCharTy;
+          case BuiltinType::UChar:
+            return T == C.UnsignedCharTy || T == C.SignedCharTy;
           case BuiltinType::Short:
             return T == C.UnsignedShortTy;
           case BuiltinType::UShort:
@@ -286,6 +287,7 @@ bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const {
           case BuiltinType::ULongLong:
             return T == C.LongLongTy;
         }
+      }
       return false;
     }
 
@@ -294,7 +296,7 @@ bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const {
       if (!PT)
         return false;
       QualType pointeeTy = PT->getPointeeType();
-      if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>())
+      if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>()) {
         switch (BT->getKind()) {
           case BuiltinType::Void:
           case BuiltinType::Char_U:
@@ -305,6 +307,7 @@ bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const {
           default:
             break;
         }
+      }
 
       return false;
     }
diff --git a/test/Sema/format-strings-funsigned-char.c b/test/Sema/format-strings-funsigned-char.c
new file mode 100644
index 0000000..4360ff8
--- /dev/null
+++ b/test/Sema/format-strings-funsigned-char.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fno-signed-char %s
+int printf(const char *restrict, ...);
+
+void pr12761(char c) {
+  printf("%hhx", c); // no warning
+}
