rsmith added a comment.

Do we really need two different notions of "definition" and "odr definition" 
here? What goes wrong if we always treat the "instantiation of a friend 
function definition" case as being a definition?



================
Comment at: include/clang/AST/Decl.h:1789
+  //     function is not used yet, but the declaration is considered a
+  //     definition, it does not allow other definition of this function.
+  //   - it does not have a user specified body, but it does not allow
----------------
it -> and


================
Comment at: include/clang/AST/Decl.h:1829-1830
 
+  /// Returns true if the function is defined and other definitions are not
+  /// allowed in the redeclaration chain.
+  ///
----------------
This will not be true in the presence of modules: we will ensure that at most 
one declaration has a body, but multiple declarations can be instantiated from 
a defined member function of a class template, for instance. So I think the 
constraint is that you're not allowed to add *more* such definitions.


================
Comment at: include/clang/AST/Decl.h:1842
+
+  /// Returns true if this declaration is a definition is the sense of ODR
+  /// checks.
----------------
is the sense -> in the sense


================
Comment at: include/clang/AST/Decl.h:1848
+      return true;
+    if (FunctionDecl *Original = getInstantiatedFromMemberFunction())
+      return Original->isOdrDefined();
----------------
I think this will do the wrong thing for an explicit specialization of a member 
of a class template:

```
template<typename T> struct A { void f() {}; };
template<> void A<int>::f();
```

Here, `A<int>::f()` is "instantiated from a member function" but it's not a 
definition, not even in the ODR sense. I think it would suffice to also check 
whether `Original` is a friend declaration here.


================
Comment at: lib/AST/Decl.cpp:2538
+    if (I->isThisDeclarationADefinition()) {
+      Definition = I->IsDeleted ? I->getCanonicalDecl() : I;
+      return true;
----------------
It seems incorrect to me for `isThisDeclarationADefinition()` to return `true` 
on a redeclaration of a deleted function: only the first declaration should be 
considered to be a definition in that case. (This special case should be in 
`isThisDeclarationADefinition()`, not in `isDefined()`.)


================
Comment at: lib/Sema/SemaDecl.cpp:11882
+
+  if (FD == Definition)
+    return;
----------------
This looks wrong to me: `CheckForFunctionRedefinition` is intended to be called 
*before* marking the function in question as a definition. If you call it 
afterwards, then the `isOdrDefined` call won't work properly because it will 
always check to see whether `FD` is a definition before checking any other 
declaration. So any case that reaches here with `FD` being a definition seems 
like a bug. I expect we're only getting here in that case due to the missing 
check for friend in `isThisDeclarationAnOdrDefinition`.


https://reviews.llvm.org/D30170



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to