<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/59752>59752</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Sema::ForceDeclarationOfImplicitMembers generates deprecated members
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          gmalecha
      </td>
    </tr>
</table>

<pre>
    Using `Sema::ForceDeclarationOfImplicitMembers` can be problematic when used in combination with `-Werror -Wdeprecated-copy` because it can generate a deprecated member that is then flagged as an error. Here's a simple piece of code that triggers this:

```c++
struct C {
  C(const C&) = default;
};
```

I'd like to extend the implementation to take an optional argument to not generate deprecated members.  Essentially, this would look like:

```c++
 void Sema::ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class, bool deprecated = true) {
   if (!CanDeclareSpecialMemberFunction(Class))
 return;
  
   // If the default constructor has not yet been declared, do so now.
   if (Class->needsImplicitDefaultConstructor())
 DeclareImplicitDefaultConstructor(Class);
  
   // If the copy constructor has not yet been declared, do so now.
   if (Class->needsImplicitCopyConstructor() and
       (deprecated or not Class->hasUserDeclaredCopyAssignment())) // <<< NEW
 DeclareImplicitCopyConstructor(Class);
  
   // If the copy assignment operator has not yet been declared, do so now.
   if (Class->needsImplicitCopyAssignment() and 
       (deprecated or not Class->hasUserDeclaredCopyConstructor())) // <<< NEW
 DeclareImplicitCopyAssignment(Class);
  
   if (getLangOpts().CPlusPlus11) {
     // If the move constructor has not yet been declared, do so now.
     if (Class->needsImplicitMoveConstructor())
 DeclareImplicitMoveConstructor(Class);
  
     // If the move assignment operator has not yet been declared, do so now.
     if (Class->needsImplicitMoveAssignment())
 DeclareImplicitMoveAssignment(Class);
   }
  
   // If the destructor has not yet been declared, do so now.
   if (Class->needsImplicitDestructor())
 DeclareImplicitDestructor(Class);
 }
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0Vl1P4zgX_jXuzVGr1ClNe5ELJqV6kd7ZWe1oxNye2CeJF8eObAeWf7-yU1oW2AKaRTI0Suzn6_gLvVetISrZxRd2sZvhGDrryrZHTaLDWW3lQ_nDK9MCW2ffqUeWX7L8cm-doB0JjQ6DsuZbc90PWgkVvlJfk_NsnYFAAzXB4GytqcegBNx3ZGD0JEEZELavlUnj4V6FLlLMb8g562B-I2lwJDCQnAs7PETAmgSOnkCFhN2SIYeBAOHUGfokAEKHAZSHEBkbjW1LEtADGkgMC_gfOWK88IDgVT9ogkGRILANCCtpQghOtS25iKN89J7tWPb4f51NTTD-Jbb01gc3igAVsOLwBqBifCOs8SE-rRnfAst3IKnBUQeWH_qxYnd6fsR-SnjNeCFBq1uCYIH-CmRkNAhJfk8mTGEGCwFvKXq1Q3yDGtC1Y-wRPxobTuG9iM4vAK68JxMUav3AeJXMw70dtQRt7W2S8K4w4M4qCR-ZN3xT_fz5BwnrZOwHjF9WGr2PMmpr9VO9McTgRkqBntIG1QDjG8aXFZqJjL4PJBTqiWU_GhHZI9mEvY1tGu4ojM4cCwFwhGV8z_gerpuU-aF6kOoaS24ddOhTuA8UoCYyICd2GdVLCz5mf794JjRpmLP8yhBJ_xjIbsKvTvDJ0xOlB2tnBxz9veknLrJPM1PZ4eGFE0Ajj6MhCdo8qa51if4I2KH_4ckdXMsIeZm2rzitT9nEuTAZY3k1Nfjt6ub1zF7q-mBgeFQAdogL6hOCe-4y5ga_Ftyrs-rDyf1D2LngJocthf-jab8NwU-ki-p3Pfr4t1w-X8PP0-7tHf3S9Dyf81d7R-9fai97n3P_qpX_YuK8bem1BfKvjt4qJ8QD6q1N8ZP2wnfvgWdrcjRwPK1msszlNt_ijMrluuArnm03xawrRV7zZdEIWtY8z2qxWhe4oWLd8O0am1rOVMkzzpc8z5YFz7NiwTk2xQovxDbf5ptVwVYZ9aj0Quu7fmFdO1Pej1RebIsLPtNYk_bp3sW5oXtIHxnn8RrmyjhmXo-tZ6tMKx_8CSWooKn8wJl6POv9K4f9bHS67EIY0u0mFbNVoRvrhbA94_tIe_iZD87-SSIwvk9iPeP7ZObvAAAA__-8XT9F">