[PATCH] D30170: Function definition may have uninstantiated body

Richard Smith - zygoloid via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 2 13:59:22 PDT 2017


rsmith added inline comments.


================
Comment at: include/clang/AST/Decl.h:1868-1871
   bool isThisDeclarationADefinition() const {
-    return IsDeleted || Body || IsLateTemplateParsed;
+    return IsDeleted || IsDefaulted || Body || IsLateTemplateParsed ||
+      hasDefiningAttr();
   }
----------------
Can you check in this change and the corresponding changes to `test/SemaCXX/cxx0x-cursory-default-delete.cpp` separately?


================
Comment at: lib/AST/Decl.cpp:2557
+      // have a body until it is used, nevertheless it is a definition. The
+      // following code must produce redeclaration error:
+      //
----------------
redeclaration -> redefinition


================
Comment at: lib/Sema/SemaDecl.cpp:11882
+
+  if (FD == Definition)
+    return;
----------------
sepavloff wrote:
> rsmith wrote:
> > 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`.
> `CheckForFunctionRedefinition` is called after the declaration is put to redeclaration chain. At this point the declaration does not have a body, so problem may arise only if the provided declaration is an instantiation. It happens when the method is called from `PerformPendingInstantiations` -> `InstantiateFunctionDefinition` -> `ActOnStartOfFunctionDef` -> `CheckForFunctionRedefinition`. In this case function body is generated for declaration that is already in redeclaration chain. If the chain is in valid state, it does not have duplicate definitions and call to `CheckForFunctionRedefinition` is redundant and this check makes shortcut return.
Ultimately, I'd like to be able to remove the special-case handling for friend function redefinitions from `TemplateDeclInstantiator::VisitFunctionDecl` and simply call `CheckForFunctionRedefinition` from there (we just need to keep the part that checks for a prior declaration marked as 'used' and instantiates the definition if so). For that to work, this function has to be able to cope with the case where `FD` is an instantiated friend and there is another instantiated friend in the redeclaration chain. In that case, `FD->isOdrDefined()` is going to determine that `FD` itself is the definition and not find the other definition (because `D->redecls()` yields `D` first).

I think the best way to make that work would be to skip `FD` when looping over redeclarations and checking for an existing definition. At that point, `isOdrDefined` is really not a general-purpose mechanism for checking for a definition, and should probably simply be inlined into here.



https://reviews.llvm.org/D30170





More information about the cfe-commits mailing list