• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===--- SemaExceptionSpec.cpp - C++ Exception Specifications ---*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file provides Sema routines for C++ exception specification testing.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/Sema/SemaInternal.h"
15 #include "clang/AST/CXXInheritance.h"
16 #include "clang/AST/Expr.h"
17 #include "clang/AST/ExprCXX.h"
18 #include "clang/AST/TypeLoc.h"
19 #include "clang/Lex/Preprocessor.h"
20 #include "clang/Basic/Diagnostic.h"
21 #include "clang/Basic/SourceManager.h"
22 #include "llvm/ADT/SmallPtrSet.h"
23 #include "llvm/ADT/SmallString.h"
24 
25 namespace clang {
26 
GetUnderlyingFunction(QualType T)27 static const FunctionProtoType *GetUnderlyingFunction(QualType T)
28 {
29   if (const PointerType *PtrTy = T->getAs<PointerType>())
30     T = PtrTy->getPointeeType();
31   else if (const ReferenceType *RefTy = T->getAs<ReferenceType>())
32     T = RefTy->getPointeeType();
33   else if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>())
34     T = MPTy->getPointeeType();
35   return T->getAs<FunctionProtoType>();
36 }
37 
38 /// CheckSpecifiedExceptionType - Check if the given type is valid in an
39 /// exception specification. Incomplete types, or pointers to incomplete types
40 /// other than void are not allowed.
CheckSpecifiedExceptionType(QualType T,const SourceRange & Range)41 bool Sema::CheckSpecifiedExceptionType(QualType T, const SourceRange &Range) {
42 
43   // This check (and the similar one below) deals with issue 437, that changes
44   // C++ 9.2p2 this way:
45   // Within the class member-specification, the class is regarded as complete
46   // within function bodies, default arguments, exception-specifications, and
47   // constructor ctor-initializers (including such things in nested classes).
48   if (T->isRecordType() && T->getAs<RecordType>()->isBeingDefined())
49     return false;
50 
51   // C++ 15.4p2: A type denoted in an exception-specification shall not denote
52   //   an incomplete type.
53   if (RequireCompleteType(Range.getBegin(), T,
54                           diag::err_incomplete_in_exception_spec,
55                           /*direct*/0, Range))
56     return true;
57 
58   // C++ 15.4p2: A type denoted in an exception-specification shall not denote
59   //   an incomplete type a pointer or reference to an incomplete type, other
60   //   than (cv) void*.
61   int kind;
62   if (const PointerType* IT = T->getAs<PointerType>()) {
63     T = IT->getPointeeType();
64     kind = 1;
65   } else if (const ReferenceType* IT = T->getAs<ReferenceType>()) {
66     T = IT->getPointeeType();
67     kind = 2;
68   } else
69     return false;
70 
71   // Again as before
72   if (T->isRecordType() && T->getAs<RecordType>()->isBeingDefined())
73     return false;
74 
75   if (!T->isVoidType() &&
76       RequireCompleteType(Range.getBegin(), T,
77                           diag::err_incomplete_in_exception_spec, kind, Range))
78     return true;
79 
80   return false;
81 }
82 
83 /// CheckDistantExceptionSpec - Check if the given type is a pointer or pointer
84 /// to member to a function with an exception specification. This means that
85 /// it is invalid to add another level of indirection.
CheckDistantExceptionSpec(QualType T)86 bool Sema::CheckDistantExceptionSpec(QualType T) {
87   if (const PointerType *PT = T->getAs<PointerType>())
88     T = PT->getPointeeType();
89   else if (const MemberPointerType *PT = T->getAs<MemberPointerType>())
90     T = PT->getPointeeType();
91   else
92     return false;
93 
94   const FunctionProtoType *FnT = T->getAs<FunctionProtoType>();
95   if (!FnT)
96     return false;
97 
98   return FnT->hasExceptionSpec();
99 }
100 
101 const FunctionProtoType *
ResolveExceptionSpec(SourceLocation Loc,const FunctionProtoType * FPT)102 Sema::ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT) {
103   if (!isUnresolvedExceptionSpec(FPT->getExceptionSpecType()))
104     return FPT;
105 
106   FunctionDecl *SourceDecl = FPT->getExceptionSpecDecl();
107   const FunctionProtoType *SourceFPT =
108       SourceDecl->getType()->castAs<FunctionProtoType>();
109 
110   // If the exception specification has already been resolved, just return it.
111   if (!isUnresolvedExceptionSpec(SourceFPT->getExceptionSpecType()))
112     return SourceFPT;
113 
114   // Compute or instantiate the exception specification now.
115   if (FPT->getExceptionSpecType() == EST_Unevaluated)
116     EvaluateImplicitExceptionSpec(Loc, cast<CXXMethodDecl>(SourceDecl));
117   else
118     InstantiateExceptionSpec(Loc, SourceDecl);
119 
120   return SourceDecl->getType()->castAs<FunctionProtoType>();
121 }
122 
CheckEquivalentExceptionSpec(FunctionDecl * Old,FunctionDecl * New)123 bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) {
124   OverloadedOperatorKind OO = New->getDeclName().getCXXOverloadedOperator();
125   bool IsOperatorNew = OO == OO_New || OO == OO_Array_New;
126   bool MissingExceptionSpecification = false;
127   bool MissingEmptyExceptionSpecification = false;
128   unsigned DiagID = diag::err_mismatched_exception_spec;
129   if (getLangOpts().MicrosoftExt)
130     DiagID = diag::warn_mismatched_exception_spec;
131 
132   if (!CheckEquivalentExceptionSpec(PDiag(DiagID),
133                                     PDiag(diag::note_previous_declaration),
134                                     Old->getType()->getAs<FunctionProtoType>(),
135                                     Old->getLocation(),
136                                     New->getType()->getAs<FunctionProtoType>(),
137                                     New->getLocation(),
138                                     &MissingExceptionSpecification,
139                                     &MissingEmptyExceptionSpecification,
140                                     /*AllowNoexceptAllMatchWithNoSpec=*/true,
141                                     IsOperatorNew))
142     return false;
143 
144   // The failure was something other than an empty exception
145   // specification; return an error.
146   if (!MissingExceptionSpecification && !MissingEmptyExceptionSpecification)
147     return true;
148 
149   const FunctionProtoType *NewProto
150     = New->getType()->getAs<FunctionProtoType>();
151 
152   // The new function declaration is only missing an empty exception
153   // specification "throw()". If the throw() specification came from a
154   // function in a system header that has C linkage, just add an empty
155   // exception specification to the "new" declaration. This is an
156   // egregious workaround for glibc, which adds throw() specifications
157   // to many libc functions as an optimization. Unfortunately, that
158   // optimization isn't permitted by the C++ standard, so we're forced
159   // to work around it here.
160   if (MissingEmptyExceptionSpecification && NewProto &&
161       (Old->getLocation().isInvalid() ||
162        Context.getSourceManager().isInSystemHeader(Old->getLocation())) &&
163       Old->isExternC()) {
164     FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo();
165     EPI.ExceptionSpecType = EST_DynamicNone;
166     QualType NewType = Context.getFunctionType(NewProto->getResultType(),
167                                                NewProto->arg_type_begin(),
168                                                NewProto->getNumArgs(),
169                                                EPI);
170     New->setType(NewType);
171     return false;
172   }
173 
174   if (MissingExceptionSpecification && NewProto) {
175     const FunctionProtoType *OldProto
176       = Old->getType()->getAs<FunctionProtoType>();
177 
178     FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo();
179     EPI.ExceptionSpecType = OldProto->getExceptionSpecType();
180     if (EPI.ExceptionSpecType == EST_Dynamic) {
181       EPI.NumExceptions = OldProto->getNumExceptions();
182       EPI.Exceptions = OldProto->exception_begin();
183     } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) {
184       // FIXME: We can't just take the expression from the old prototype. It
185       // likely contains references to the old prototype's parameters.
186     }
187 
188     // Update the type of the function with the appropriate exception
189     // specification.
190     QualType NewType = Context.getFunctionType(NewProto->getResultType(),
191                                                NewProto->arg_type_begin(),
192                                                NewProto->getNumArgs(),
193                                                EPI);
194     New->setType(NewType);
195 
196     // If exceptions are disabled, suppress the warning about missing
197     // exception specifications for new and delete operators.
198     if (!getLangOpts().CXXExceptions) {
199       switch (New->getDeclName().getCXXOverloadedOperator()) {
200       case OO_New:
201       case OO_Array_New:
202       case OO_Delete:
203       case OO_Array_Delete:
204         if (New->getDeclContext()->isTranslationUnit())
205           return false;
206         break;
207 
208       default:
209         break;
210       }
211     }
212 
213     // Warn about the lack of exception specification.
214     SmallString<128> ExceptionSpecString;
215     llvm::raw_svector_ostream OS(ExceptionSpecString);
216     switch (OldProto->getExceptionSpecType()) {
217     case EST_DynamicNone:
218       OS << "throw()";
219       break;
220 
221     case EST_Dynamic: {
222       OS << "throw(";
223       bool OnFirstException = true;
224       for (FunctionProtoType::exception_iterator E = OldProto->exception_begin(),
225                                               EEnd = OldProto->exception_end();
226            E != EEnd;
227            ++E) {
228         if (OnFirstException)
229           OnFirstException = false;
230         else
231           OS << ", ";
232 
233         OS << E->getAsString(getPrintingPolicy());
234       }
235       OS << ")";
236       break;
237     }
238 
239     case EST_BasicNoexcept:
240       OS << "noexcept";
241       break;
242 
243     case EST_ComputedNoexcept:
244       OS << "noexcept(";
245       OldProto->getNoexceptExpr()->printPretty(OS, 0, getPrintingPolicy());
246       OS << ")";
247       break;
248 
249     default:
250       llvm_unreachable("This spec type is compatible with none.");
251     }
252     OS.flush();
253 
254     SourceLocation FixItLoc;
255     if (TypeSourceInfo *TSInfo = New->getTypeSourceInfo()) {
256       TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
257       if (const FunctionTypeLoc *FTLoc = dyn_cast<FunctionTypeLoc>(&TL))
258         FixItLoc = PP.getLocForEndOfToken(FTLoc->getLocalRangeEnd());
259     }
260 
261     if (FixItLoc.isInvalid())
262       Diag(New->getLocation(), diag::warn_missing_exception_specification)
263         << New << OS.str();
264     else {
265       // FIXME: This will get more complicated with C++0x
266       // late-specified return types.
267       Diag(New->getLocation(), diag::warn_missing_exception_specification)
268         << New << OS.str()
269         << FixItHint::CreateInsertion(FixItLoc, " " + OS.str().str());
270     }
271 
272     if (!Old->getLocation().isInvalid())
273       Diag(Old->getLocation(), diag::note_previous_declaration);
274 
275     return false;
276   }
277 
278   Diag(New->getLocation(), DiagID);
279   Diag(Old->getLocation(), diag::note_previous_declaration);
280   return true;
281 }
282 
283 /// CheckEquivalentExceptionSpec - Check if the two types have equivalent
284 /// exception specifications. Exception specifications are equivalent if
285 /// they allow exactly the same set of exception types. It does not matter how
286 /// that is achieved. See C++ [except.spec]p2.
CheckEquivalentExceptionSpec(const FunctionProtoType * Old,SourceLocation OldLoc,const FunctionProtoType * New,SourceLocation NewLoc)287 bool Sema::CheckEquivalentExceptionSpec(
288     const FunctionProtoType *Old, SourceLocation OldLoc,
289     const FunctionProtoType *New, SourceLocation NewLoc) {
290   unsigned DiagID = diag::err_mismatched_exception_spec;
291   if (getLangOpts().MicrosoftExt)
292     DiagID = diag::warn_mismatched_exception_spec;
293   return CheckEquivalentExceptionSpec(
294                                       PDiag(DiagID),
295                                       PDiag(diag::note_previous_declaration),
296                                       Old, OldLoc, New, NewLoc);
297 }
298 
299 /// CheckEquivalentExceptionSpec - Check if the two types have compatible
300 /// exception specifications. See C++ [except.spec]p3.
CheckEquivalentExceptionSpec(const PartialDiagnostic & DiagID,const PartialDiagnostic & NoteID,const FunctionProtoType * Old,SourceLocation OldLoc,const FunctionProtoType * New,SourceLocation NewLoc,bool * MissingExceptionSpecification,bool * MissingEmptyExceptionSpecification,bool AllowNoexceptAllMatchWithNoSpec,bool IsOperatorNew)301 bool Sema::CheckEquivalentExceptionSpec(const PartialDiagnostic &DiagID,
302                                         const PartialDiagnostic & NoteID,
303                                         const FunctionProtoType *Old,
304                                         SourceLocation OldLoc,
305                                         const FunctionProtoType *New,
306                                         SourceLocation NewLoc,
307                                         bool *MissingExceptionSpecification,
308                                         bool*MissingEmptyExceptionSpecification,
309                                         bool AllowNoexceptAllMatchWithNoSpec,
310                                         bool IsOperatorNew) {
311   // Just completely ignore this under -fno-exceptions.
312   if (!getLangOpts().CXXExceptions)
313     return false;
314 
315   if (MissingExceptionSpecification)
316     *MissingExceptionSpecification = false;
317 
318   if (MissingEmptyExceptionSpecification)
319     *MissingEmptyExceptionSpecification = false;
320 
321   Old = ResolveExceptionSpec(NewLoc, Old);
322   if (!Old)
323     return false;
324   New = ResolveExceptionSpec(NewLoc, New);
325   if (!New)
326     return false;
327 
328   // C++0x [except.spec]p3: Two exception-specifications are compatible if:
329   //   - both are non-throwing, regardless of their form,
330   //   - both have the form noexcept(constant-expression) and the constant-
331   //     expressions are equivalent,
332   //   - both are dynamic-exception-specifications that have the same set of
333   //     adjusted types.
334   //
335   // C++0x [except.spec]p12: An exception-specifcation is non-throwing if it is
336   //   of the form throw(), noexcept, or noexcept(constant-expression) where the
337   //   constant-expression yields true.
338   //
339   // C++0x [except.spec]p4: If any declaration of a function has an exception-
340   //   specifier that is not a noexcept-specification allowing all exceptions,
341   //   all declarations [...] of that function shall have a compatible
342   //   exception-specification.
343   //
344   // That last point basically means that noexcept(false) matches no spec.
345   // It's considered when AllowNoexceptAllMatchWithNoSpec is true.
346 
347   ExceptionSpecificationType OldEST = Old->getExceptionSpecType();
348   ExceptionSpecificationType NewEST = New->getExceptionSpecType();
349 
350   assert(!isUnresolvedExceptionSpec(OldEST) &&
351          !isUnresolvedExceptionSpec(NewEST) &&
352          "Shouldn't see unknown exception specifications here");
353 
354   // Shortcut the case where both have no spec.
355   if (OldEST == EST_None && NewEST == EST_None)
356     return false;
357 
358   FunctionProtoType::NoexceptResult OldNR = Old->getNoexceptSpec(Context);
359   FunctionProtoType::NoexceptResult NewNR = New->getNoexceptSpec(Context);
360   if (OldNR == FunctionProtoType::NR_BadNoexcept ||
361       NewNR == FunctionProtoType::NR_BadNoexcept)
362     return false;
363 
364   // Dependent noexcept specifiers are compatible with each other, but nothing
365   // else.
366   // One noexcept is compatible with another if the argument is the same
367   if (OldNR == NewNR &&
368       OldNR != FunctionProtoType::NR_NoNoexcept &&
369       NewNR != FunctionProtoType::NR_NoNoexcept)
370     return false;
371   if (OldNR != NewNR &&
372       OldNR != FunctionProtoType::NR_NoNoexcept &&
373       NewNR != FunctionProtoType::NR_NoNoexcept) {
374     Diag(NewLoc, DiagID);
375     if (NoteID.getDiagID() != 0)
376       Diag(OldLoc, NoteID);
377     return true;
378   }
379 
380   // The MS extension throw(...) is compatible with itself.
381   if (OldEST == EST_MSAny && NewEST == EST_MSAny)
382     return false;
383 
384   // It's also compatible with no spec.
385   if ((OldEST == EST_None && NewEST == EST_MSAny) ||
386       (OldEST == EST_MSAny && NewEST == EST_None))
387     return false;
388 
389   // It's also compatible with noexcept(false).
390   if (OldEST == EST_MSAny && NewNR == FunctionProtoType::NR_Throw)
391     return false;
392   if (NewEST == EST_MSAny && OldNR == FunctionProtoType::NR_Throw)
393     return false;
394 
395   // As described above, noexcept(false) matches no spec only for functions.
396   if (AllowNoexceptAllMatchWithNoSpec) {
397     if (OldEST == EST_None && NewNR == FunctionProtoType::NR_Throw)
398       return false;
399     if (NewEST == EST_None && OldNR == FunctionProtoType::NR_Throw)
400       return false;
401   }
402 
403   // Any non-throwing specifications are compatible.
404   bool OldNonThrowing = OldNR == FunctionProtoType::NR_Nothrow ||
405                         OldEST == EST_DynamicNone;
406   bool NewNonThrowing = NewNR == FunctionProtoType::NR_Nothrow ||
407                         NewEST == EST_DynamicNone;
408   if (OldNonThrowing && NewNonThrowing)
409     return false;
410 
411   // As a special compatibility feature, under C++0x we accept no spec and
412   // throw(std::bad_alloc) as equivalent for operator new and operator new[].
413   // This is because the implicit declaration changed, but old code would break.
414   if (getLangOpts().CPlusPlus0x && IsOperatorNew) {
415     const FunctionProtoType *WithExceptions = 0;
416     if (OldEST == EST_None && NewEST == EST_Dynamic)
417       WithExceptions = New;
418     else if (OldEST == EST_Dynamic && NewEST == EST_None)
419       WithExceptions = Old;
420     if (WithExceptions && WithExceptions->getNumExceptions() == 1) {
421       // One has no spec, the other throw(something). If that something is
422       // std::bad_alloc, all conditions are met.
423       QualType Exception = *WithExceptions->exception_begin();
424       if (CXXRecordDecl *ExRecord = Exception->getAsCXXRecordDecl()) {
425         IdentifierInfo* Name = ExRecord->getIdentifier();
426         if (Name && Name->getName() == "bad_alloc") {
427           // It's called bad_alloc, but is it in std?
428           DeclContext* DC = ExRecord->getDeclContext();
429           DC = DC->getEnclosingNamespaceContext();
430           if (NamespaceDecl* NS = dyn_cast<NamespaceDecl>(DC)) {
431             IdentifierInfo* NSName = NS->getIdentifier();
432             DC = DC->getParent();
433             if (NSName && NSName->getName() == "std" &&
434                 DC->getEnclosingNamespaceContext()->isTranslationUnit()) {
435               return false;
436             }
437           }
438         }
439       }
440     }
441   }
442 
443   // At this point, the only remaining valid case is two matching dynamic
444   // specifications. We return here unless both specifications are dynamic.
445   if (OldEST != EST_Dynamic || NewEST != EST_Dynamic) {
446     if (MissingExceptionSpecification && Old->hasExceptionSpec() &&
447         !New->hasExceptionSpec()) {
448       // The old type has an exception specification of some sort, but
449       // the new type does not.
450       *MissingExceptionSpecification = true;
451 
452       if (MissingEmptyExceptionSpecification && OldNonThrowing) {
453         // The old type has a throw() or noexcept(true) exception specification
454         // and the new type has no exception specification, and the caller asked
455         // to handle this itself.
456         *MissingEmptyExceptionSpecification = true;
457       }
458 
459       return true;
460     }
461 
462     Diag(NewLoc, DiagID);
463     if (NoteID.getDiagID() != 0)
464       Diag(OldLoc, NoteID);
465     return true;
466   }
467 
468   assert(OldEST == EST_Dynamic && NewEST == EST_Dynamic &&
469       "Exception compatibility logic error: non-dynamic spec slipped through.");
470 
471   bool Success = true;
472   // Both have a dynamic exception spec. Collect the first set, then compare
473   // to the second.
474   llvm::SmallPtrSet<CanQualType, 8> OldTypes, NewTypes;
475   for (FunctionProtoType::exception_iterator I = Old->exception_begin(),
476        E = Old->exception_end(); I != E; ++I)
477     OldTypes.insert(Context.getCanonicalType(*I).getUnqualifiedType());
478 
479   for (FunctionProtoType::exception_iterator I = New->exception_begin(),
480        E = New->exception_end(); I != E && Success; ++I) {
481     CanQualType TypePtr = Context.getCanonicalType(*I).getUnqualifiedType();
482     if(OldTypes.count(TypePtr))
483       NewTypes.insert(TypePtr);
484     else
485       Success = false;
486   }
487 
488   Success = Success && OldTypes.size() == NewTypes.size();
489 
490   if (Success) {
491     return false;
492   }
493   Diag(NewLoc, DiagID);
494   if (NoteID.getDiagID() != 0)
495     Diag(OldLoc, NoteID);
496   return true;
497 }
498 
499 /// CheckExceptionSpecSubset - Check whether the second function type's
500 /// exception specification is a subset (or equivalent) of the first function
501 /// type. This is used by override and pointer assignment checks.
CheckExceptionSpecSubset(const PartialDiagnostic & DiagID,const PartialDiagnostic & NoteID,const FunctionProtoType * Superset,SourceLocation SuperLoc,const FunctionProtoType * Subset,SourceLocation SubLoc)502 bool Sema::CheckExceptionSpecSubset(
503     const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
504     const FunctionProtoType *Superset, SourceLocation SuperLoc,
505     const FunctionProtoType *Subset, SourceLocation SubLoc) {
506 
507   // Just auto-succeed under -fno-exceptions.
508   if (!getLangOpts().CXXExceptions)
509     return false;
510 
511   // FIXME: As usual, we could be more specific in our error messages, but
512   // that better waits until we've got types with source locations.
513 
514   if (!SubLoc.isValid())
515     SubLoc = SuperLoc;
516 
517   // Resolve the exception specifications, if needed.
518   Superset = ResolveExceptionSpec(SuperLoc, Superset);
519   if (!Superset)
520     return false;
521   Subset = ResolveExceptionSpec(SubLoc, Subset);
522   if (!Subset)
523     return false;
524 
525   ExceptionSpecificationType SuperEST = Superset->getExceptionSpecType();
526 
527   // If superset contains everything, we're done.
528   if (SuperEST == EST_None || SuperEST == EST_MSAny)
529     return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc);
530 
531   // If there are dependent noexcept specs, assume everything is fine. Unlike
532   // with the equivalency check, this is safe in this case, because we don't
533   // want to merge declarations. Checks after instantiation will catch any
534   // omissions we make here.
535   // We also shortcut checking if a noexcept expression was bad.
536 
537   FunctionProtoType::NoexceptResult SuperNR =Superset->getNoexceptSpec(Context);
538   if (SuperNR == FunctionProtoType::NR_BadNoexcept ||
539       SuperNR == FunctionProtoType::NR_Dependent)
540     return false;
541 
542   // Another case of the superset containing everything.
543   if (SuperNR == FunctionProtoType::NR_Throw)
544     return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc);
545 
546   ExceptionSpecificationType SubEST = Subset->getExceptionSpecType();
547 
548   assert(!isUnresolvedExceptionSpec(SuperEST) &&
549          !isUnresolvedExceptionSpec(SubEST) &&
550          "Shouldn't see unknown exception specifications here");
551 
552   // It does not. If the subset contains everything, we've failed.
553   if (SubEST == EST_None || SubEST == EST_MSAny) {
554     Diag(SubLoc, DiagID);
555     if (NoteID.getDiagID() != 0)
556       Diag(SuperLoc, NoteID);
557     return true;
558   }
559 
560   FunctionProtoType::NoexceptResult SubNR = Subset->getNoexceptSpec(Context);
561   if (SubNR == FunctionProtoType::NR_BadNoexcept ||
562       SubNR == FunctionProtoType::NR_Dependent)
563     return false;
564 
565   // Another case of the subset containing everything.
566   if (SubNR == FunctionProtoType::NR_Throw) {
567     Diag(SubLoc, DiagID);
568     if (NoteID.getDiagID() != 0)
569       Diag(SuperLoc, NoteID);
570     return true;
571   }
572 
573   // If the subset contains nothing, we're done.
574   if (SubEST == EST_DynamicNone || SubNR == FunctionProtoType::NR_Nothrow)
575     return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc);
576 
577   // Otherwise, if the superset contains nothing, we've failed.
578   if (SuperEST == EST_DynamicNone || SuperNR == FunctionProtoType::NR_Nothrow) {
579     Diag(SubLoc, DiagID);
580     if (NoteID.getDiagID() != 0)
581       Diag(SuperLoc, NoteID);
582     return true;
583   }
584 
585   assert(SuperEST == EST_Dynamic && SubEST == EST_Dynamic &&
586          "Exception spec subset: non-dynamic case slipped through.");
587 
588   // Neither contains everything or nothing. Do a proper comparison.
589   for (FunctionProtoType::exception_iterator SubI = Subset->exception_begin(),
590        SubE = Subset->exception_end(); SubI != SubE; ++SubI) {
591     // Take one type from the subset.
592     QualType CanonicalSubT = Context.getCanonicalType(*SubI);
593     // Unwrap pointers and references so that we can do checks within a class
594     // hierarchy. Don't unwrap member pointers; they don't have hierarchy
595     // conversions on the pointee.
596     bool SubIsPointer = false;
597     if (const ReferenceType *RefTy = CanonicalSubT->getAs<ReferenceType>())
598       CanonicalSubT = RefTy->getPointeeType();
599     if (const PointerType *PtrTy = CanonicalSubT->getAs<PointerType>()) {
600       CanonicalSubT = PtrTy->getPointeeType();
601       SubIsPointer = true;
602     }
603     bool SubIsClass = CanonicalSubT->isRecordType();
604     CanonicalSubT = CanonicalSubT.getLocalUnqualifiedType();
605 
606     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
607                        /*DetectVirtual=*/false);
608 
609     bool Contained = false;
610     // Make sure it's in the superset.
611     for (FunctionProtoType::exception_iterator SuperI =
612            Superset->exception_begin(), SuperE = Superset->exception_end();
613          SuperI != SuperE; ++SuperI) {
614       QualType CanonicalSuperT = Context.getCanonicalType(*SuperI);
615       // SubT must be SuperT or derived from it, or pointer or reference to
616       // such types.
617       if (const ReferenceType *RefTy = CanonicalSuperT->getAs<ReferenceType>())
618         CanonicalSuperT = RefTy->getPointeeType();
619       if (SubIsPointer) {
620         if (const PointerType *PtrTy = CanonicalSuperT->getAs<PointerType>())
621           CanonicalSuperT = PtrTy->getPointeeType();
622         else {
623           continue;
624         }
625       }
626       CanonicalSuperT = CanonicalSuperT.getLocalUnqualifiedType();
627       // If the types are the same, move on to the next type in the subset.
628       if (CanonicalSubT == CanonicalSuperT) {
629         Contained = true;
630         break;
631       }
632 
633       // Otherwise we need to check the inheritance.
634       if (!SubIsClass || !CanonicalSuperT->isRecordType())
635         continue;
636 
637       Paths.clear();
638       if (!IsDerivedFrom(CanonicalSubT, CanonicalSuperT, Paths))
639         continue;
640 
641       if (Paths.isAmbiguous(Context.getCanonicalType(CanonicalSuperT)))
642         continue;
643 
644       // Do this check from a context without privileges.
645       switch (CheckBaseClassAccess(SourceLocation(),
646                                    CanonicalSuperT, CanonicalSubT,
647                                    Paths.front(),
648                                    /*Diagnostic*/ 0,
649                                    /*ForceCheck*/ true,
650                                    /*ForceUnprivileged*/ true)) {
651       case AR_accessible: break;
652       case AR_inaccessible: continue;
653       case AR_dependent:
654         llvm_unreachable("access check dependent for unprivileged context");
655       case AR_delayed:
656         llvm_unreachable("access check delayed in non-declaration");
657       }
658 
659       Contained = true;
660       break;
661     }
662     if (!Contained) {
663       Diag(SubLoc, DiagID);
664       if (NoteID.getDiagID() != 0)
665         Diag(SuperLoc, NoteID);
666       return true;
667     }
668   }
669   // We've run half the gauntlet.
670   return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc);
671 }
672 
CheckSpecForTypesEquivalent(Sema & S,const PartialDiagnostic & DiagID,const PartialDiagnostic & NoteID,QualType Target,SourceLocation TargetLoc,QualType Source,SourceLocation SourceLoc)673 static bool CheckSpecForTypesEquivalent(Sema &S,
674     const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
675     QualType Target, SourceLocation TargetLoc,
676     QualType Source, SourceLocation SourceLoc)
677 {
678   const FunctionProtoType *TFunc = GetUnderlyingFunction(Target);
679   if (!TFunc)
680     return false;
681   const FunctionProtoType *SFunc = GetUnderlyingFunction(Source);
682   if (!SFunc)
683     return false;
684 
685   return S.CheckEquivalentExceptionSpec(DiagID, NoteID, TFunc, TargetLoc,
686                                         SFunc, SourceLoc);
687 }
688 
689 /// CheckParamExceptionSpec - Check if the parameter and return types of the
690 /// two functions have equivalent exception specs. This is part of the
691 /// assignment and override compatibility check. We do not check the parameters
692 /// of parameter function pointers recursively, as no sane programmer would
693 /// even be able to write such a function type.
CheckParamExceptionSpec(const PartialDiagnostic & NoteID,const FunctionProtoType * Target,SourceLocation TargetLoc,const FunctionProtoType * Source,SourceLocation SourceLoc)694 bool Sema::CheckParamExceptionSpec(const PartialDiagnostic & NoteID,
695     const FunctionProtoType *Target, SourceLocation TargetLoc,
696     const FunctionProtoType *Source, SourceLocation SourceLoc)
697 {
698   if (CheckSpecForTypesEquivalent(*this,
699                            PDiag(diag::err_deep_exception_specs_differ) << 0,
700                                   PDiag(),
701                                   Target->getResultType(), TargetLoc,
702                                   Source->getResultType(), SourceLoc))
703     return true;
704 
705   // We shouldn't even be testing this unless the arguments are otherwise
706   // compatible.
707   assert(Target->getNumArgs() == Source->getNumArgs() &&
708          "Functions have different argument counts.");
709   for (unsigned i = 0, E = Target->getNumArgs(); i != E; ++i) {
710     if (CheckSpecForTypesEquivalent(*this,
711                            PDiag(diag::err_deep_exception_specs_differ) << 1,
712                                     PDiag(),
713                                     Target->getArgType(i), TargetLoc,
714                                     Source->getArgType(i), SourceLoc))
715       return true;
716   }
717   return false;
718 }
719 
CheckExceptionSpecCompatibility(Expr * From,QualType ToType)720 bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType)
721 {
722   // First we check for applicability.
723   // Target type must be a function, function pointer or function reference.
724   const FunctionProtoType *ToFunc = GetUnderlyingFunction(ToType);
725   if (!ToFunc)
726     return false;
727 
728   // SourceType must be a function or function pointer.
729   const FunctionProtoType *FromFunc = GetUnderlyingFunction(From->getType());
730   if (!FromFunc)
731     return false;
732 
733   // Now we've got the correct types on both sides, check their compatibility.
734   // This means that the source of the conversion can only throw a subset of
735   // the exceptions of the target, and any exception specs on arguments or
736   // return types must be equivalent.
737   return CheckExceptionSpecSubset(PDiag(diag::err_incompatible_exception_specs),
738                                   PDiag(), ToFunc,
739                                   From->getSourceRange().getBegin(),
740                                   FromFunc, SourceLocation());
741 }
742 
CheckOverridingFunctionExceptionSpec(const CXXMethodDecl * New,const CXXMethodDecl * Old)743 bool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New,
744                                                 const CXXMethodDecl *Old) {
745   if (getLangOpts().CPlusPlus0x && isa<CXXDestructorDecl>(New)) {
746     // Don't check uninstantiated template destructors at all. We can only
747     // synthesize correct specs after the template is instantiated.
748     if (New->getParent()->isDependentType())
749       return false;
750     if (New->getParent()->isBeingDefined()) {
751       // The destructor might be updated once the definition is finished. So
752       // remember it and check later.
753       DelayedDestructorExceptionSpecChecks.push_back(std::make_pair(
754         cast<CXXDestructorDecl>(New), cast<CXXDestructorDecl>(Old)));
755       return false;
756     }
757   }
758   unsigned DiagID = diag::err_override_exception_spec;
759   if (getLangOpts().MicrosoftExt)
760     DiagID = diag::warn_override_exception_spec;
761   return CheckExceptionSpecSubset(PDiag(DiagID),
762                                   PDiag(diag::note_overridden_virtual_function),
763                                   Old->getType()->getAs<FunctionProtoType>(),
764                                   Old->getLocation(),
765                                   New->getType()->getAs<FunctionProtoType>(),
766                                   New->getLocation());
767 }
768 
canSubExprsThrow(Sema & S,const Expr * CE)769 static CanThrowResult canSubExprsThrow(Sema &S, const Expr *CE) {
770   Expr *E = const_cast<Expr*>(CE);
771   CanThrowResult R = CT_Cannot;
772   for (Expr::child_range I = E->children(); I && R != CT_Can; ++I)
773     R = mergeCanThrow(R, S.canThrow(cast<Expr>(*I)));
774   return R;
775 }
776 
canCalleeThrow(Sema & S,const Expr * E,const Decl * D,bool NullThrows=true)777 static CanThrowResult canCalleeThrow(Sema &S, const Expr *E,
778                                            const Decl *D,
779                                            bool NullThrows = true) {
780   if (!D)
781     return NullThrows ? CT_Can : CT_Cannot;
782 
783   // See if we can get a function type from the decl somehow.
784   const ValueDecl *VD = dyn_cast<ValueDecl>(D);
785   if (!VD) // If we have no clue what we're calling, assume the worst.
786     return CT_Can;
787 
788   // As an extension, we assume that __attribute__((nothrow)) functions don't
789   // throw.
790   if (isa<FunctionDecl>(D) && D->hasAttr<NoThrowAttr>())
791     return CT_Cannot;
792 
793   QualType T = VD->getType();
794   const FunctionProtoType *FT;
795   if ((FT = T->getAs<FunctionProtoType>())) {
796   } else if (const PointerType *PT = T->getAs<PointerType>())
797     FT = PT->getPointeeType()->getAs<FunctionProtoType>();
798   else if (const ReferenceType *RT = T->getAs<ReferenceType>())
799     FT = RT->getPointeeType()->getAs<FunctionProtoType>();
800   else if (const MemberPointerType *MT = T->getAs<MemberPointerType>())
801     FT = MT->getPointeeType()->getAs<FunctionProtoType>();
802   else if (const BlockPointerType *BT = T->getAs<BlockPointerType>())
803     FT = BT->getPointeeType()->getAs<FunctionProtoType>();
804 
805   if (!FT)
806     return CT_Can;
807 
808   FT = S.ResolveExceptionSpec(E->getLocStart(), FT);
809   if (!FT)
810     return CT_Can;
811 
812   return FT->isNothrow(S.Context) ? CT_Cannot : CT_Can;
813 }
814 
canDynamicCastThrow(const CXXDynamicCastExpr * DC)815 static CanThrowResult canDynamicCastThrow(const CXXDynamicCastExpr *DC) {
816   if (DC->isTypeDependent())
817     return CT_Dependent;
818 
819   if (!DC->getTypeAsWritten()->isReferenceType())
820     return CT_Cannot;
821 
822   if (DC->getSubExpr()->isTypeDependent())
823     return CT_Dependent;
824 
825   return DC->getCastKind() == clang::CK_Dynamic? CT_Can : CT_Cannot;
826 }
827 
canTypeidThrow(Sema & S,const CXXTypeidExpr * DC)828 static CanThrowResult canTypeidThrow(Sema &S, const CXXTypeidExpr *DC) {
829   if (DC->isTypeOperand())
830     return CT_Cannot;
831 
832   Expr *Op = DC->getExprOperand();
833   if (Op->isTypeDependent())
834     return CT_Dependent;
835 
836   const RecordType *RT = Op->getType()->getAs<RecordType>();
837   if (!RT)
838     return CT_Cannot;
839 
840   if (!cast<CXXRecordDecl>(RT->getDecl())->isPolymorphic())
841     return CT_Cannot;
842 
843   if (Op->Classify(S.Context).isPRValue())
844     return CT_Cannot;
845 
846   return CT_Can;
847 }
848 
canThrow(const Expr * E)849 CanThrowResult Sema::canThrow(const Expr *E) {
850   // C++ [expr.unary.noexcept]p3:
851   //   [Can throw] if in a potentially-evaluated context the expression would
852   //   contain:
853   switch (E->getStmtClass()) {
854   case Expr::CXXThrowExprClass:
855     //   - a potentially evaluated throw-expression
856     return CT_Can;
857 
858   case Expr::CXXDynamicCastExprClass: {
859     //   - a potentially evaluated dynamic_cast expression dynamic_cast<T>(v),
860     //     where T is a reference type, that requires a run-time check
861     CanThrowResult CT = canDynamicCastThrow(cast<CXXDynamicCastExpr>(E));
862     if (CT == CT_Can)
863       return CT;
864     return mergeCanThrow(CT, canSubExprsThrow(*this, E));
865   }
866 
867   case Expr::CXXTypeidExprClass:
868     //   - a potentially evaluated typeid expression applied to a glvalue
869     //     expression whose type is a polymorphic class type
870     return canTypeidThrow(*this, cast<CXXTypeidExpr>(E));
871 
872     //   - a potentially evaluated call to a function, member function, function
873     //     pointer, or member function pointer that does not have a non-throwing
874     //     exception-specification
875   case Expr::CallExprClass:
876   case Expr::CXXMemberCallExprClass:
877   case Expr::CXXOperatorCallExprClass:
878   case Expr::UserDefinedLiteralClass: {
879     const CallExpr *CE = cast<CallExpr>(E);
880     CanThrowResult CT;
881     if (E->isTypeDependent())
882       CT = CT_Dependent;
883     else if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens()))
884       CT = CT_Cannot;
885     else
886       CT = canCalleeThrow(*this, E, CE->getCalleeDecl());
887     if (CT == CT_Can)
888       return CT;
889     return mergeCanThrow(CT, canSubExprsThrow(*this, E));
890   }
891 
892   case Expr::CXXConstructExprClass:
893   case Expr::CXXTemporaryObjectExprClass: {
894     CanThrowResult CT = canCalleeThrow(*this, E,
895         cast<CXXConstructExpr>(E)->getConstructor());
896     if (CT == CT_Can)
897       return CT;
898     return mergeCanThrow(CT, canSubExprsThrow(*this, E));
899   }
900 
901   case Expr::LambdaExprClass: {
902     const LambdaExpr *Lambda = cast<LambdaExpr>(E);
903     CanThrowResult CT = CT_Cannot;
904     for (LambdaExpr::capture_init_iterator Cap = Lambda->capture_init_begin(),
905                                         CapEnd = Lambda->capture_init_end();
906          Cap != CapEnd; ++Cap)
907       CT = mergeCanThrow(CT, canThrow(*Cap));
908     return CT;
909   }
910 
911   case Expr::CXXNewExprClass: {
912     CanThrowResult CT;
913     if (E->isTypeDependent())
914       CT = CT_Dependent;
915     else
916       CT = canCalleeThrow(*this, E, cast<CXXNewExpr>(E)->getOperatorNew());
917     if (CT == CT_Can)
918       return CT;
919     return mergeCanThrow(CT, canSubExprsThrow(*this, E));
920   }
921 
922   case Expr::CXXDeleteExprClass: {
923     CanThrowResult CT;
924     QualType DTy = cast<CXXDeleteExpr>(E)->getDestroyedType();
925     if (DTy.isNull() || DTy->isDependentType()) {
926       CT = CT_Dependent;
927     } else {
928       CT = canCalleeThrow(*this, E,
929                           cast<CXXDeleteExpr>(E)->getOperatorDelete());
930       if (const RecordType *RT = DTy->getAs<RecordType>()) {
931         const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
932         CT = mergeCanThrow(CT, canCalleeThrow(*this, E, RD->getDestructor()));
933       }
934       if (CT == CT_Can)
935         return CT;
936     }
937     return mergeCanThrow(CT, canSubExprsThrow(*this, E));
938   }
939 
940   case Expr::CXXBindTemporaryExprClass: {
941     // The bound temporary has to be destroyed again, which might throw.
942     CanThrowResult CT = canCalleeThrow(*this, E,
943       cast<CXXBindTemporaryExpr>(E)->getTemporary()->getDestructor());
944     if (CT == CT_Can)
945       return CT;
946     return mergeCanThrow(CT, canSubExprsThrow(*this, E));
947   }
948 
949     // ObjC message sends are like function calls, but never have exception
950     // specs.
951   case Expr::ObjCMessageExprClass:
952   case Expr::ObjCPropertyRefExprClass:
953   case Expr::ObjCSubscriptRefExprClass:
954     return CT_Can;
955 
956     // All the ObjC literals that are implemented as calls are
957     // potentially throwing unless we decide to close off that
958     // possibility.
959   case Expr::ObjCArrayLiteralClass:
960   case Expr::ObjCDictionaryLiteralClass:
961   case Expr::ObjCBoxedExprClass:
962     return CT_Can;
963 
964     // Many other things have subexpressions, so we have to test those.
965     // Some are simple:
966   case Expr::ConditionalOperatorClass:
967   case Expr::CompoundLiteralExprClass:
968   case Expr::CXXConstCastExprClass:
969   case Expr::CXXDefaultArgExprClass:
970   case Expr::CXXReinterpretCastExprClass:
971   case Expr::DesignatedInitExprClass:
972   case Expr::ExprWithCleanupsClass:
973   case Expr::ExtVectorElementExprClass:
974   case Expr::InitListExprClass:
975   case Expr::MemberExprClass:
976   case Expr::ObjCIsaExprClass:
977   case Expr::ObjCIvarRefExprClass:
978   case Expr::ParenExprClass:
979   case Expr::ParenListExprClass:
980   case Expr::ShuffleVectorExprClass:
981   case Expr::VAArgExprClass:
982     return canSubExprsThrow(*this, E);
983 
984     // Some might be dependent for other reasons.
985   case Expr::ArraySubscriptExprClass:
986   case Expr::BinaryOperatorClass:
987   case Expr::CompoundAssignOperatorClass:
988   case Expr::CStyleCastExprClass:
989   case Expr::CXXStaticCastExprClass:
990   case Expr::CXXFunctionalCastExprClass:
991   case Expr::ImplicitCastExprClass:
992   case Expr::MaterializeTemporaryExprClass:
993   case Expr::UnaryOperatorClass: {
994     CanThrowResult CT = E->isTypeDependent() ? CT_Dependent : CT_Cannot;
995     return mergeCanThrow(CT, canSubExprsThrow(*this, E));
996   }
997 
998     // FIXME: We should handle StmtExpr, but that opens a MASSIVE can of worms.
999   case Expr::StmtExprClass:
1000     return CT_Can;
1001 
1002   case Expr::ChooseExprClass:
1003     if (E->isTypeDependent() || E->isValueDependent())
1004       return CT_Dependent;
1005     return canThrow(cast<ChooseExpr>(E)->getChosenSubExpr(Context));
1006 
1007   case Expr::GenericSelectionExprClass:
1008     if (cast<GenericSelectionExpr>(E)->isResultDependent())
1009       return CT_Dependent;
1010     return canThrow(cast<GenericSelectionExpr>(E)->getResultExpr());
1011 
1012     // Some expressions are always dependent.
1013   case Expr::CXXDependentScopeMemberExprClass:
1014   case Expr::CXXUnresolvedConstructExprClass:
1015   case Expr::DependentScopeDeclRefExprClass:
1016     return CT_Dependent;
1017 
1018   case Expr::AsTypeExprClass:
1019   case Expr::BinaryConditionalOperatorClass:
1020   case Expr::BlockExprClass:
1021   case Expr::CUDAKernelCallExprClass:
1022   case Expr::DeclRefExprClass:
1023   case Expr::ObjCBridgedCastExprClass:
1024   case Expr::ObjCIndirectCopyRestoreExprClass:
1025   case Expr::ObjCProtocolExprClass:
1026   case Expr::ObjCSelectorExprClass:
1027   case Expr::OffsetOfExprClass:
1028   case Expr::PackExpansionExprClass:
1029   case Expr::PseudoObjectExprClass:
1030   case Expr::SubstNonTypeTemplateParmExprClass:
1031   case Expr::SubstNonTypeTemplateParmPackExprClass:
1032   case Expr::UnaryExprOrTypeTraitExprClass:
1033   case Expr::UnresolvedLookupExprClass:
1034   case Expr::UnresolvedMemberExprClass:
1035     // FIXME: Can any of the above throw?  If so, when?
1036     return CT_Cannot;
1037 
1038   case Expr::AddrLabelExprClass:
1039   case Expr::ArrayTypeTraitExprClass:
1040   case Expr::AtomicExprClass:
1041   case Expr::BinaryTypeTraitExprClass:
1042   case Expr::TypeTraitExprClass:
1043   case Expr::CXXBoolLiteralExprClass:
1044   case Expr::CXXNoexceptExprClass:
1045   case Expr::CXXNullPtrLiteralExprClass:
1046   case Expr::CXXPseudoDestructorExprClass:
1047   case Expr::CXXScalarValueInitExprClass:
1048   case Expr::CXXThisExprClass:
1049   case Expr::CXXUuidofExprClass:
1050   case Expr::CharacterLiteralClass:
1051   case Expr::ExpressionTraitExprClass:
1052   case Expr::FloatingLiteralClass:
1053   case Expr::GNUNullExprClass:
1054   case Expr::ImaginaryLiteralClass:
1055   case Expr::ImplicitValueInitExprClass:
1056   case Expr::IntegerLiteralClass:
1057   case Expr::ObjCEncodeExprClass:
1058   case Expr::ObjCStringLiteralClass:
1059   case Expr::ObjCBoolLiteralExprClass:
1060   case Expr::OpaqueValueExprClass:
1061   case Expr::PredefinedExprClass:
1062   case Expr::SizeOfPackExprClass:
1063   case Expr::StringLiteralClass:
1064   case Expr::UnaryTypeTraitExprClass:
1065     // These expressions can never throw.
1066     return CT_Cannot;
1067 
1068 #define STMT(CLASS, PARENT) case Expr::CLASS##Class:
1069 #define STMT_RANGE(Base, First, Last)
1070 #define LAST_STMT_RANGE(BASE, FIRST, LAST)
1071 #define EXPR(CLASS, PARENT)
1072 #define ABSTRACT_STMT(STMT)
1073 #include "clang/AST/StmtNodes.inc"
1074   case Expr::NoStmtClass:
1075     llvm_unreachable("Invalid class for expression");
1076   }
1077   llvm_unreachable("Bogus StmtClass");
1078 }
1079 
1080 } // end namespace clang
1081