<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Is there anything special in the builedbot configuration? Are you still observing intermittent failures?<div class=""><br class=""></div><div class="">I’m double checking if we see similar failures internally but so far looks like everything is working fine. I’ve only seen a single failure <a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap-ubsan/builds/18616" class="">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap-ubsan/builds/18616</a></div><div class=""><br class=""></div><div class="">At the moment I don’t know what might be causing the non-determinism. The type checking depends on the parsing order. We rely that</div><div class=""><br class=""></div><div class="">@interface ParameterizedContainer<T> (Cat)</div><div class=""><br class=""></div><div class="">is parsed before</div><div class=""><br class=""></div><div class="">- (ParameterizedContainer<T> *)inCategory;</div><div class=""><br class=""></div><div class="">So we check type parameter T is consistent with original @interface before using it. What is also confusing is that there is only a single error. I  expect both a category and an extension to have same errors.<br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Apr 5, 2020, at 10:10, Nico Weber <<a href="mailto:thakis@chromium.org" class="">thakis@chromium.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">The test here flakily fails, maybe 1 in 10 times: <a href="http://45.33.8.238/mac/11180/step_7.txt" class="">http://45.33.8.238/mac/11180/step_7.txt</a><div class=""><br class=""></div><div class="">error: 'error' diagnostics seen but not expected: <br class="">  File /Users/thakis/src/llvm-project/clang/test/SemaObjC/parameterized_classes_subst.m Line 479: type argument 'T' (aka 'id') does not satisfy the bound ('id<NSCopying>') of type parameter 'T'<br class="">error: 'note' diagnostics seen but not expected: <br class="">  File /Users/thakis/src/llvm-project/clang/test/SemaObjC/parameterized_classes_subst.m Line 475: type parameter 'T' declared here<br class="">2 errors generated.<br class=""></div><div class=""><br class=""></div><div class="">Maybe if this is emitted depends on the order of something in a data structure that has no deterministic order, or similar?</div></div><br class=""><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Apr 3, 2020 at 7:29 PM Volodymyr Sapsai via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br class="">
Author: Volodymyr Sapsai<br class="">
Date: 2020-04-03T16:29:02-07:00<br class="">
New Revision: a8c8b627f23f204fb621bd2a8c495cfc8bc16ae7<br class="">
<br class="">
URL: <a href="https://github.com/llvm/llvm-project/commit/a8c8b627f23f204fb621bd2a8c495cfc8bc16ae7" rel="noreferrer" target="_blank" class="">https://github.com/llvm/llvm-project/commit/a8c8b627f23f204fb621bd2a8c495cfc8bc16ae7</a><br class="">
DIFF: <a href="https://github.com/llvm/llvm-project/commit/a8c8b627f23f204fb621bd2a8c495cfc8bc16ae7.diff" rel="noreferrer" target="_blank" class="">https://github.com/llvm/llvm-project/commit/a8c8b627f23f204fb621bd2a8c495cfc8bc16ae7.diff</a><br class="">
<br class="">
LOG: [ObjC generics] Fix not inheriting type bounds in categories/extensions.<br class="">
<br class="">
When a category/extension doesn't repeat a type bound, corresponding<br class="">
type parameter is substituted with `id` when used as a type argument. As<br class="">
a result, in the added test case it was causing errors like<br class="">
<br class="">
> type argument 'T' (aka 'id') does not satisfy the bound ('id<NSCopying>') of type parameter 'T'<br class="">
<br class="">
We are already checking that type parameters should be consistent<br class="">
everywhere (see `checkTypeParamListConsistency`) and update<br class="">
`ObjCTypeParamDecl` to have correct underlying type. And when we use the<br class="">
type parameter as a method return type or a method parameter type, it is<br class="">
substituted to the bounded type. But when we use the type parameter as a<br class="">
type argument, we check `ObjCTypeParamType` that wasn't updated and<br class="">
remains `id`.<br class="">
<br class="">
Fix by updating not only `ObjCTypeParamDecl` UnderlyingType but also<br class="">
TypeForDecl as we use the underlying type to create a canonical type for<br class="">
`ObjCTypeParamType` (see `ASTContext::getObjCTypeParamType`).<br class="">
<br class="">
This is a different approach to fixing the issue. The previous one was<br class="">
02c2ab3d8872416589bd1a6ca3dfb96ba373a3b9 which was reverted in<br class="">
4c539e8da1b3de38a53ef3f7497f5c45a3243b61. The problem with the previous<br class="">
approach was that `ObjCTypeParamType::desugar` was returning underlying<br class="">
type for `ObjCTypeParamDecl` without applying any protocols stored in<br class="">
`ObjCTypeParamType`. It caused inconsistencies in comparing types before<br class="">
and after desugaring.<br class="">
<br class="">
<a href="rdar://problem/54329242" class="">rdar://problem/54329242</a><br class="">
<br class="">
Reviewed By: erik.pilkington<br class="">
<br class="">
Differential Revision: <a href="https://reviews.llvm.org/D72872" rel="noreferrer" target="_blank" class="">https://reviews.llvm.org/D72872</a><br class="">
<br class="">
Added: <br class="">
<br class="">
<br class="">
Modified: <br class="">
    clang/include/clang/AST/ASTContext.h<br class="">
    clang/lib/AST/ASTContext.cpp<br class="">
    clang/lib/AST/Type.cpp<br class="">
    clang/lib/Sema/SemaDeclObjC.cpp<br class="">
    clang/test/SemaObjC/parameterized_classes_collection_literal.m<br class="">
    clang/test/SemaObjC/parameterized_classes_subst.m<br class="">
<br class="">
Removed: <br class="">
<br class="">
<br class="">
<br class="">
################################################################################<br class="">
diff  --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h<br class="">
index 6813ab58874e..6360f18217c7 100644<br class="">
--- a/clang/include/clang/AST/ASTContext.h<br class="">
+++ b/clang/include/clang/AST/ASTContext.h<br class="">
@@ -1442,6 +1442,8 @@ class ASTContext : public RefCountedBase<ASTContext> {<br class="">
<br class="">
   QualType getObjCTypeParamType(const ObjCTypeParamDecl *Decl,<br class="">
                                 ArrayRef<ObjCProtocolDecl *> protocols) const;<br class="">
+  void adjustObjCTypeParamBoundType(const ObjCTypeParamDecl *Orig,<br class="">
+                                    ObjCTypeParamDecl *New) const;<br class="">
<br class="">
   bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);<br class="">
<br class="">
<br class="">
diff  --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp<br class="">
index 1e81e0a67b4d..06dcb6fa0580 100644<br class="">
--- a/clang/lib/AST/ASTContext.cpp<br class="">
+++ b/clang/lib/AST/ASTContext.cpp<br class="">
@@ -4874,6 +4874,17 @@ ASTContext::getObjCTypeParamType(const ObjCTypeParamDecl *Decl,<br class="">
   return QualType(newType, 0);<br class="">
 }<br class="">
<br class="">
+void ASTContext::adjustObjCTypeParamBoundType(const ObjCTypeParamDecl *Orig,<br class="">
+                                              ObjCTypeParamDecl *New) const {<br class="">
+  New->setTypeSourceInfo(getTrivialTypeSourceInfo(Orig->getUnderlyingType()));<br class="">
+  // Update TypeForDecl after updating TypeSourceInfo.<br class="">
+  auto NewTypeParamTy = cast<ObjCTypeParamType>(New->getTypeForDecl());<br class="">
+  SmallVector<ObjCProtocolDecl *, 8> protocols;<br class="">
+  protocols.append(NewTypeParamTy->qual_begin(), NewTypeParamTy->qual_end());<br class="">
+  QualType UpdatedTy = getObjCTypeParamType(New, protocols);<br class="">
+  New->setTypeForDecl(UpdatedTy.getTypePtr());<br class="">
+}<br class="">
+<br class="">
 /// ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's<br class="">
 /// protocol list adopt all protocols in QT's qualified-id protocol<br class="">
 /// list.<br class="">
<br class="">
diff  --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp<br class="">
index 3428437c3146..7c65378261ad 100644<br class="">
--- a/clang/lib/AST/Type.cpp<br class="">
+++ b/clang/lib/AST/Type.cpp<br class="">
@@ -3534,6 +3534,7 @@ void ObjCTypeParamType::Profile(llvm::FoldingSetNodeID &ID,<br class="">
                                 const ObjCTypeParamDecl *OTPDecl,<br class="">
                                 ArrayRef<ObjCProtocolDecl *> protocols) {<br class="">
   ID.AddPointer(OTPDecl);<br class="">
+  ID.AddPointer(OTPDecl->getUnderlyingType().getAsOpaquePtr());<br class="">
   ID.AddInteger(protocols.size());<br class="">
   for (auto proto : protocols)<br class="">
     ID.AddPointer(proto);<br class="">
<br class="">
diff  --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp<br class="">
index 934e1a23141c..6db57898e378 100644<br class="">
--- a/clang/lib/Sema/SemaDeclObjC.cpp<br class="">
+++ b/clang/lib/Sema/SemaDeclObjC.cpp<br class="">
@@ -938,8 +938,7 @@ static bool checkTypeParamListConsistency(Sema &S,<br class="">
<br class="">
       // Override the new type parameter's bound type with the previous type,<br class="">
       // so that it's consistent.<br class="">
-      newTypeParam->setTypeSourceInfo(<br class="">
-        S.Context.getTrivialTypeSourceInfo(prevTypeParam->getUnderlyingType()));<br class="">
+      S.Context.adjustObjCTypeParamBoundType(prevTypeParam, newTypeParam);<br class="">
       continue;<br class="">
     }<br class="">
<br class="">
@@ -966,8 +965,7 @@ static bool checkTypeParamListConsistency(Sema &S,<br class="">
     }<br class="">
<br class="">
     // Update the new type parameter's bound to match the previous one.<br class="">
-    newTypeParam->setTypeSourceInfo(<br class="">
-      S.Context.getTrivialTypeSourceInfo(prevTypeParam->getUnderlyingType()));<br class="">
+    S.Context.adjustObjCTypeParamBoundType(prevTypeParam, newTypeParam);<br class="">
   }<br class="">
<br class="">
   return false;<br class="">
<br class="">
diff  --git a/clang/test/SemaObjC/parameterized_classes_collection_literal.m b/clang/test/SemaObjC/parameterized_classes_collection_literal.m<br class="">
index 472746e09db9..034d2e8da217 100644<br class="">
--- a/clang/test/SemaObjC/parameterized_classes_collection_literal.m<br class="">
+++ b/clang/test/SemaObjC/parameterized_classes_collection_literal.m<br class="">
@@ -29,7 +29,9 @@ + (instancetype)arrayWithObjects:(const T [])objects count:(NSUInteger)cnt;<br class="">
 @end<br class="">
<br class="">
 @interface NSDictionary<K, V> : NSObject <NSCopying><br class="">
-+ (instancetype)dictionaryWithObjects:(const V [])objects forKeys:(const K [])keys count:(NSUInteger)cnt;<br class="">
++ (instancetype)dictionaryWithObjects:(const V [])objects<br class="">
+                              forKeys:(const K <NSCopying> [])keys<br class="">
+                                count:(NSUInteger)cnt;<br class="">
 @end<br class="">
<br class="">
 void testArrayLiteral(void) {<br class="">
@@ -50,3 +52,9 @@ void testDictionaryLiteral(void) {<br class="">
     @"world" : @"blah" // expected-warning{{object of type 'NSString *' is not compatible with dictionary value type 'NSNumber *'}}<br class="">
   };<br class="">
 }<br class="">
+<br class="">
+void testCastingInDictionaryLiteral(NSString *arg) {<br class="">
+  NSDictionary *dict = @{<br class="">
+    (id)arg : @"foo",<br class="">
+  };<br class="">
+}<br class="">
<br class="">
diff  --git a/clang/test/SemaObjC/parameterized_classes_subst.m b/clang/test/SemaObjC/parameterized_classes_subst.m<br class="">
index d14a6e9deb40..b6d884760d29 100644<br class="">
--- a/clang/test/SemaObjC/parameterized_classes_subst.m<br class="">
+++ b/clang/test/SemaObjC/parameterized_classes_subst.m<br class="">
@@ -467,3 +467,17 @@ - (void)mapUsingBlock:(id (^)(id))block {<br class="">
 - (void)mapUsingBlock2:(id)block { // expected-warning{{conflicting parameter types in implementation}}<br class="">
 }<br class="">
 @end<br class="">
+<br class="">
+// --------------------------------------------------------------------------<br class="">
+// Use a type parameter as a type argument.<br class="">
+// --------------------------------------------------------------------------<br class="">
+// Type bounds in a category/extension are omitted. <a href="rdar://problem/54329242" class="">rdar://problem/54329242</a><br class="">
+@interface ParameterizedContainer<T : id<NSCopying>><br class="">
+- (ParameterizedContainer<T> *)inInterface;<br class="">
+@end<br class="">
+@interface ParameterizedContainer<T> (Cat)<br class="">
+- (ParameterizedContainer<T> *)inCategory;<br class="">
+@end<br class="">
+@interface ParameterizedContainer<U> ()<br class="">
+- (ParameterizedContainer<U> *)inExtension;<br class="">
+@end<br class="">
<br class="">
<br class="">
<br class="">
_______________________________________________<br class="">
cfe-commits mailing list<br class="">
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank" class="">cfe-commits@lists.llvm.org</a><br class="">
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank" class="">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br class="">
</blockquote></div>
</div></blockquote></div><br class=""></div></body></html>