Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Added NCCE/CS and AD

...

Similarly, before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any glvalue that refers to the original object may be used but only in limited ways. For an object under construction or destruction, see 12.7. Otherwise, such a glvalue refers to allocated storage, and using the properties of the glvalue that do not depend on its value is well-defined. The program has undefined behavior if:
    — an lvalue-to-rvalue conversion is applied to such a glvalue,
    — the glvalue is used to access a non-static data member or call a non-static member function of the object, or
    — the glvalue is bound to a reference to a virtual base class, or
    — the glvalue is used as the operand of a dynamic_cast or as the operand of typeid.

Do not use an object outside of its lifetime, except in the ways described above as being well-defined.

...

Code Block
bgColor#ccccff
langc
auto g() {
  int i = 12;
  return [=] () mutable {
    i = 100;
    return i;
  };
}

void f() {
  int i = g()();
}

Noncompliant Code Example

std::initializer_list<> object is constructed from an initializer list as if the implementation allocated a temporary array and passed it to the std::initializer_list<> constructor. This temporary array has the same lifetime as other temporary objects, except that initializing a std::initializer_list<> object from the array extends the lifetime of the array exactly like binding a reference to a temporary [ISO/IEC 14882-2014]. In this noncompliant code example, a member variable of type std::initializer_list<int> is list initialized within the constructor's ctor-initializier. Under these circumstances, the conceptual temporary array's lifetime ends once the constructor exits, and so accessing any elements of the std::initializer_list<int> member variable results in undefined behavior.

Code Block
bgColor#FFcccc
langc
#include <initializer_list>
#include <iostream>

class C {
  std::initializer_list<int> L;
  
public:
  C() : L{1, 2, 3} {}
  
  int first() const { return *L.begin(); }
};

void f() {
  C c;
  std::cout << c.first();
}

Compliant Solution

In this compliant solution, the std::initializer_list<int> member variable is replaced with a std::vector<int>, which copies the elements of the initializer list to the container instead of relying on a dangling reference to the temporary array.

Code Block
bgColor#ccccff
langc
#include <initializer_list>
#include <iostream>
#include <vector>
 
class C {
  std::vector<int> L;
  
public:
  C() : L{1, 2, 3} {}
  
  int first() const { return *L.begin(); }
};
 
void f() {
  C c;
  std::cout << c.first();
}

Risk  Risk Assessment

Referencing an object outside of its lifetime can result in an attacker being able to run arbitrary code.

...

Tool

Version

Checker

Description

   
Clang
Include Page
Clang_V
Clang_V

-Wdangling-initializer-list

Catches some lifetime issues related to incorrect use of std::initializer_list<> 

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

...

[ISO/IEC 14882-2014]3.8, "Object Lifetime"
8.5.4, "List-Initialization" 
[Coverity 2007] 

 

...